|
|
1.1 root 1:
2: #define SOFTFLOAT_68K
3:
4: #include <stdint.h>
5: #include <stdlib.h>
6: #include "softfloat/softfloat.h"
7:
8:
9: /*
10: * QEMU float support
11: *
12: * The code in this source file is derived from release 2a of the SoftFloat
13: * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
14: * some later contributions) are provided under that license, as detailed below.
15: * It has subsequently been modified by contributors to the QEMU Project,
16: * so some portions are provided under:
17: * the SoftFloat-2a license
18: * the BSD license
19: * GPL-v2-or-later
20: *
21: * Any future contributions to this file after December 1st 2014 will be
22: * taken to be licensed under the Softfloat-2a license unless specifically
23: * indicated otherwise.
24: */
25:
26: /*
27: ===============================================================================
28: This C source file is part of the SoftFloat IEC/IEEE Floating-point
29: Arithmetic Package, Release 2a.
30:
31: Written by John R. Hauser. This work was made possible in part by the
32: International Computer Science Institute, located at Suite 600, 1947 Center
33: Street, Berkeley, California 94704. Funding was partially provided by the
34: National Science Foundation under grant MIP-9311980. The original version
35: of this code was written as part of a project to build a fixed-point vector
36: processor in collaboration with the University of California at Berkeley,
37: overseen by Profs. Nelson Morgan and John Wawrzynek. More information
38: is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
39: arithmetic/SoftFloat.html'.
40:
41: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
42: has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
43: TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
44: PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
45: AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
46:
47: Derivative works are acceptable, even for commercial purposes, so long as
48: (1) they include prominent notice that the work is derivative, and (2) they
49: include prominent notice akin to these four paragraphs for those parts of
50: this code that are retained.
51:
52: ===============================================================================
53: */
54:
55: /* BSD licensing:
56: * Copyright (c) 2006, Fabrice Bellard
57: * All rights reserved.
58: *
59: * Redistribution and use in source and binary forms, with or without
60: * modification, are permitted provided that the following conditions are met:
61: *
62: * 1. Redistributions of source code must retain the above copyright notice,
63: * this list of conditions and the following disclaimer.
64: *
65: * 2. Redistributions in binary form must reproduce the above copyright notice,
66: * this list of conditions and the following disclaimer in the documentation
67: * and/or other materials provided with the distribution.
68: *
69: * 3. Neither the name of the copyright holder nor the names of its contributors
70: * may be used to endorse or promote products derived from this software without
71: * specific prior written permission.
72: *
73: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
74: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
77: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
78: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
79: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
80: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
81: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
82: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
83: * THE POSSIBILITY OF SUCH DAMAGE.
84: */
85:
86: /* Portions of this work are licensed under the terms of the GNU GPL,
87: * version 2 or later. See the COPYING file in the top-level directory.
88: */
89:
90: /* We only need stdlib for abort() */
91:
92: /*----------------------------------------------------------------------------
93: | Primitive arithmetic functions, including multi-word arithmetic, and
94: | division and square root approximations. (Can be specialized to target if
95: | desired.)
96: *----------------------------------------------------------------------------*/
97: #include "softfloat-macros.h"
98:
99: /*----------------------------------------------------------------------------
100: | Variables for storing sign, exponent and significand of internal extended
101: | double-precision floating-point value for external use.
102: *----------------------------------------------------------------------------*/
103: flag floatx80_internal_sign = 0;
104: int32_t floatx80_internal_exp = 0;
105: uint64_t floatx80_internal_sig = 0;
106: int32_t floatx80_internal_exp0 = 0;
107: uint64_t floatx80_internal_sig0 = 0;
108: uint64_t floatx80_internal_sig1 = 0;
109: int8_t floatx80_internal_precision = 80;
110: int8_t floatx80_internal_mode = float_round_nearest_even;
111:
112: /*----------------------------------------------------------------------------
113: | Functions for storing sign, exponent and significand of extended
114: | double-precision floating-point intermediate result for external use.
115: *----------------------------------------------------------------------------*/
116: floatx80 roundSaveFloatx80Internal( int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status )
117: {
118: int64_t roundIncrement, roundMask, roundBits;
119: flag increment;
120:
121: if ( roundingPrecision == 80 ) {
122: goto precision80;
123: } else if ( roundingPrecision == 64 ) {
124: roundIncrement = LIT64( 0x0000000000000400 );
125: roundMask = LIT64( 0x00000000000007FF );
126: } else if ( roundingPrecision == 32 ) {
127: roundIncrement = LIT64( 0x0000008000000000 );
128: roundMask = LIT64( 0x000000FFFFFFFFFF );
129: } else {
130: goto precision80;
131: }
132:
133: zSig0 |= ( zSig1 != 0 );
134: if ( status->float_rounding_mode != float_round_nearest_even ) {
135: if ( status->float_rounding_mode == float_round_to_zero ) {
136: roundIncrement = 0;
137: } else {
138: roundIncrement = roundMask;
139: if ( zSign ) {
140: if ( status->float_rounding_mode == float_round_up ) roundIncrement = 0;
141: } else {
142: if ( status->float_rounding_mode == float_round_down ) roundIncrement = 0;
143: }
144: }
145: }
146:
147: roundBits = zSig0 & roundMask;
148:
149: zSig0 += roundIncrement;
150: if ( zSig0 < roundIncrement ) {
151: ++zExp;
152: zSig0 = LIT64( 0x8000000000000000 );
153: }
154: roundIncrement = roundMask + 1;
155: if ( status->float_rounding_mode == float_round_nearest_even && ( roundBits<<1 == roundIncrement ) ) {
156: roundMask |= roundIncrement;
157: }
158: zSig0 &= ~ roundMask;
159: if ( zSig0 == 0 ) zExp = 0;
160: return packFloatx80( zSign, zExp, zSig0 );
161:
162: precision80:
163: increment = ( (int64_t) zSig1 < 0 );
164: if ( status->float_rounding_mode != float_round_nearest_even ) {
165: if ( status->float_rounding_mode == float_round_to_zero ) {
166: increment = 0;
167: } else {
168: if ( zSign ) {
169: increment = ( status->float_rounding_mode == float_round_down ) && zSig1;
170: } else {
171: increment = ( status->float_rounding_mode == float_round_up ) && zSig1;
172: }
173: }
174: }
175: if ( increment ) {
176: ++zSig0;
177: if ( zSig0 == 0 ) {
178: ++zExp;
179: zSig0 = LIT64( 0x8000000000000000 );
180: } else {
181: zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & ( status->float_rounding_mode == float_round_nearest_even ) );
182: }
183: } else {
184: if ( zSig0 == 0 ) zExp = 0;
185: }
186: return packFloatx80( zSign, zExp, zSig0 );
187: }
188:
189: static void saveFloatx80Internal( int8_t prec, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status )
190: {
191: floatx80_internal_sign = zSign;
192: floatx80_internal_exp = zExp;
193: floatx80_internal_sig0 = zSig0;
194: floatx80_internal_sig1 = zSig1;
195: floatx80_internal_precision = prec;
196: floatx80_internal_mode = status->float_rounding_mode;
197: }
198:
199: static void saveFloat64Internal( flag zSign, int16_t zExp, uint64_t zSig, float_status *status )
200: {
201: floatx80_internal_sign = zSign;
202: floatx80_internal_exp = zExp + 0x3C01;
203: floatx80_internal_sig0 = zSig<<1;
204: floatx80_internal_sig1 = 0;
205: floatx80_internal_precision = 64;
206: floatx80_internal_mode = status->float_rounding_mode;
207: }
208:
209: static void saveFloat32Internal( flag zSign, int16_t zExp, uint32_t zSig, float_status *status )
210: {
211: floatx80 z = roundSaveFloatx80Internal( 32, zSign, zExp + 0x3F81, ( (uint64_t) zSig )<<33, 0, status );
212:
213: floatx80_internal_sign = zSign;
214: floatx80_internal_exp = extractFloatx80Exp( z );
215: floatx80_internal_sig = extractFloatx80Frac( z );
216: floatx80_internal_exp0 = zExp + 0x3F81;
217: floatx80_internal_sig0 = ( (uint64_t) zSig )<<33;
218: floatx80_internal_sig1 = 0;
219: }
220:
221: /*----------------------------------------------------------------------------
222: | Functions for returning sign, exponent and significand of extended
223: | double-precision floating-point intermediate result for external use.
224: *----------------------------------------------------------------------------*/
225:
226: void getRoundedFloatInternal( int8_t roundingPrecision, flag *pzSign, int32_t *pzExp, uint64_t *pzSig )
227: {
228: int64_t roundIncrement, roundMask, roundBits;
229: flag increment;
230:
231: flag zSign = floatx80_internal_sign;
232: int32_t zExp = floatx80_internal_exp;
233: uint64_t zSig0 = floatx80_internal_sig0;
234: uint64_t zSig1 = floatx80_internal_sig1;
235:
236: if ( roundingPrecision == 80 ) {
237: goto precision80;
238: } else if ( roundingPrecision == 64 ) {
239: roundIncrement = LIT64( 0x0000000000000400 );
240: roundMask = LIT64( 0x00000000000007FF );
241: } else if ( roundingPrecision == 32 ) {
242: roundIncrement = LIT64( 0x0000008000000000 );
243: roundMask = LIT64( 0x000000FFFFFFFFFF );
244: } else {
245: goto precision80;
246: }
247:
248: zSig0 |= ( zSig1 != 0 );
249: if ( floatx80_internal_mode != float_round_nearest_even ) {
250: if ( floatx80_internal_mode == float_round_to_zero ) {
251: roundIncrement = 0;
252: } else {
253: roundIncrement = roundMask;
254: if ( zSign ) {
255: if ( floatx80_internal_mode == float_round_up ) roundIncrement = 0;
256: } else {
257: if ( floatx80_internal_mode == float_round_down ) roundIncrement = 0;
258: }
259: }
260: }
261:
262: roundBits = zSig0 & roundMask;
263:
264: zSig0 += roundIncrement;
265: if ( zSig0 < roundIncrement ) {
266: ++zExp;
267: zSig0 = LIT64( 0x8000000000000000 );
268: }
269: roundIncrement = roundMask + 1;
270: if ( floatx80_internal_mode == float_round_nearest_even && ( roundBits<<1 == roundIncrement ) ) {
271: roundMask |= roundIncrement;
272: }
273: zSig0 &= ~ roundMask;
274: if ( zSig0 == 0 ) zExp = 0;
275:
276: *pzSign = zSign;
277: *pzExp = zExp;
278: *pzSig = zSig0;
279: return;
280:
281: precision80:
282: increment = ( (int64_t) zSig1 < 0 );
283: if ( floatx80_internal_mode != float_round_nearest_even ) {
284: if ( floatx80_internal_mode == float_round_to_zero ) {
285: increment = 0;
286: } else {
287: if ( zSign ) {
288: increment = ( floatx80_internal_mode == float_round_down ) && zSig1;
289: } else {
290: increment = ( floatx80_internal_mode == float_round_up ) && zSig1;
291: }
292: }
293: }
294: if ( increment ) {
295: ++zSig0;
296: if ( zSig0 == 0 ) {
297: ++zExp;
298: zSig0 = LIT64( 0x8000000000000000 );
299: } else {
300: zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & ( floatx80_internal_mode == float_round_nearest_even ) );
301: }
302: } else {
303: if ( zSig0 == 0 ) zExp = 0;
304: }
305:
306: *pzSign = zSign;
307: *pzExp = zExp;
308: *pzSig = zSig0;
309: }
310:
311: floatx80 getFloatInternalOverflow( void )
312: {
313: flag zSign;
314: int32_t zExp;
315: uint64_t zSig;
316:
317: getRoundedFloatInternal( floatx80_internal_precision, &zSign, &zExp, &zSig );
318:
319: if (zExp > (0x7fff + 0x6000)) { // catastrophic
320: zExp = 0;
321: } else {
322: zExp -= 0x6000;
323: }
324:
325: return packFloatx80( zSign, zExp, zSig );
326:
327: }
328:
329: floatx80 getFloatInternalUnderflow( void )
330: {
331: flag zSign;
332: int32_t zExp;
333: uint64_t zSig;
334:
335: getRoundedFloatInternal( floatx80_internal_precision, &zSign, &zExp, &zSig );
336:
337: if (zExp < (0x0000 - 0x6000)) { // catastrophic
338: zExp = 0;
339: } else {
340: zExp += 0x6000;
341: }
342:
343: return packFloatx80( zSign, zExp, zSig );
344:
345: }
346:
347: floatx80 getFloatInternalRoundedAll( void )
348: {
349: flag zSign;
350: int32_t zExp;
351: uint64_t zSig, zSig32, zSig64, zSig80;
352:
353: if (floatx80_internal_precision == 80) {
354: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80 );
355: zSig = zSig80;
356: } else if (floatx80_internal_precision == 64) {
357: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80 );
358: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64 );
359: zSig = zSig64;
360: zSig |= zSig80 & LIT64( 0x00000000000007FF );
361: } else {
362: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80 );
363: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64 );
364: getRoundedFloatInternal( 32, &zSign, &zExp, &zSig32 );
365: zSig = zSig32;
366: zSig |= zSig64 & LIT64( 0x000000FFFFFFFFFF );
367: zSig |= zSig80 & LIT64( 0x00000000000007FF );
368: }
369:
370: return packFloatx80( zSign, zExp & 0x7FFF, zSig );
371:
372: }
373:
374: floatx80 getFloatInternalRoundedSome( void )
375: {
376: flag zSign;
377: int32_t zExp;
378: uint64_t zSig, zSig32, zSig64, zSig80;
379:
380: if (floatx80_internal_precision == 80) {
381: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80 );
382: zSig = zSig80;
383: } else if (floatx80_internal_precision == 64) {
384: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64 );
385: zSig80 = floatx80_internal_sig0;
386: if (zSig64 != (zSig80 & LIT64( 0xFFFFFFFFFFFFF800 ))) {
387: zSig80++;
388: }
389: zSig = zSig64;
390: zSig |= zSig80 & LIT64( 0x00000000000007FF );
391: } else {
392: getRoundedFloatInternal( 32, &zSign, &zExp, &zSig32 );
393: zSig80 = floatx80_internal_sig0;
394: if (zSig32 != (zSig80 & LIT64( 0xFFFFFF0000000000 ))) {
395: zSig80++;
396: }
397: zSig = zSig32;
398: zSig |= zSig80 & LIT64( 0x000000FFFFFFFFFF );
399: }
400:
401: return packFloatx80( zSign, zExp & 0x7FFF, zSig );
402:
403: }
404:
405: floatx80 getFloatInternalFloatx80( void )
406: {
407: flag zSign;
408: int32_t zExp;
409: uint64_t zSig;
410:
411: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig );
412:
413: return packFloatx80( zSign, zExp & 0x7FFF, zSig );
414:
415: }
416:
417: floatx80 getFloatInternalUnrounded( void )
418: {
419: flag zSign = floatx80_internal_sign;
420: int32_t zExp = floatx80_internal_exp;
421: uint64_t zSig = floatx80_internal_sig0;
422:
423: return packFloatx80( zSign, zExp & 0x7FFF, zSig );
424:
425: }
426:
427: uint64_t getFloatInternalGRS( void )
428: {
429: #if 1
430: if (floatx80_internal_sig1)
431: return 5;
432:
433: if (floatx80_internal_precision == 64 &&
434: floatx80_internal_sig0 & LIT64( 0x00000000000007FF )) {
435: return 1;
436: }
437: if (floatx80_internal_precision == 32 &&
438: floatx80_internal_sig0 & LIT64( 0x000000FFFFFFFFFF )) {
439: return 1;
440: }
441:
442: return 0;
443: #else
444: uint64_t roundbits;
445: shift64RightJamming(floatx80_internal_sig1, 61, &roundbits);
446:
447: return roundbits;
448: #endif
449: }
450:
451: /*----------------------------------------------------------------------------
452: | Functions and definitions to determine: (1) whether tininess for underflow
453: | is detected before or after rounding by default, (2) what (if anything)
454: | happens when exceptions are raised, (3) how signaling NaNs are distinguished
455: | from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
456: | are propagated from function inputs to output. These details are target-
457: | specific.
458: *----------------------------------------------------------------------------*/
459: #include "softfloat-specialize.h"
460:
461: /*----------------------------------------------------------------------------
462: | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
463: | and 7, and returns the properly rounded 32-bit integer corresponding to the
464: | input. If `zSign' is 1, the input is negated before being converted to an
465: | integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
466: | is simply rounded to an integer, with the inexact exception raised if the
467: | input cannot be represented exactly as an integer. However, if the fixed-
468: | point input is too large, the invalid exception is raised and the largest
469: | positive or negative integer is returned.
470: *----------------------------------------------------------------------------*/
471:
472: static int32_t roundAndPackInt32(flag zSign, uint64_t absZ, float_status *status)
473: {
474: int8_t roundingMode;
475: flag roundNearestEven;
476: int8_t roundIncrement, roundBits;
477: int32_t z;
478:
479: roundingMode = status->float_rounding_mode;
480: roundNearestEven = ( roundingMode == float_round_nearest_even );
481: switch (roundingMode) {
482: case float_round_nearest_even:
483: case float_round_ties_away:
484: roundIncrement = 0x40;
485: break;
486: case float_round_to_zero:
487: roundIncrement = 0;
488: break;
489: case float_round_up:
490: roundIncrement = zSign ? 0 : 0x7f;
491: break;
492: case float_round_down:
493: roundIncrement = zSign ? 0x7f : 0;
494: break;
495: default:
496: abort();
497: }
498: roundBits = absZ & 0x7F;
499: absZ = ( absZ + roundIncrement )>>7;
500: absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
501: z = absZ;
502: if ( zSign ) z = - z;
503: if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
504: float_raise(float_flag_invalid, status);
505: return zSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
506: }
507: if (roundBits) {
508: status->float_exception_flags |= float_flag_inexact;
509: }
510: return z;
511:
512: }
513:
514:
515: #ifdef SOFTFLOAT_68K // 30-01-2017: Added for Previous
516: static int16_t roundAndPackInt16( flag zSign, uint64_t absZ, float_status *status )
517: {
518: int8_t roundingMode;
519: flag roundNearestEven;
520: int8_t roundIncrement, roundBits;
521: int16_t z;
522:
523: roundingMode = status->float_rounding_mode;
524: roundNearestEven = ( roundingMode == float_round_nearest_even );
525: roundIncrement = 0x40;
526: if ( ! roundNearestEven ) {
527: if ( roundingMode == float_round_to_zero ) {
528: roundIncrement = 0;
529: }
530: else {
531: roundIncrement = 0x7F;
532: if ( zSign ) {
533: if ( roundingMode == float_round_up ) roundIncrement = 0;
534: }
535: else {
536: if ( roundingMode == float_round_down ) roundIncrement = 0;
537: }
538: }
539: }
540: roundBits = absZ & 0x7F;
541: absZ = ( absZ + roundIncrement )>>7;
542: absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
543: z = absZ;
544: if ( zSign ) z = - z;
545: z = (int16_t) z;
546: if ( ( absZ>>16 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
547: float_raise( float_flag_invalid, status );
548: return zSign ? (int16_t) 0x8000 : 0x7FFF;
549: }
550: if ( roundBits ) status->float_exception_flags |= float_flag_inexact;
551: return z;
552:
553: }
554:
555: static int8_t roundAndPackInt8( flag zSign, uint64_t absZ, float_status *status )
556: {
557: int8_t roundingMode;
558: flag roundNearestEven;
559: int8_t roundIncrement, roundBits;
560: int8_t z;
561:
562: roundingMode = status->float_rounding_mode;
563: roundNearestEven = ( roundingMode == float_round_nearest_even );
564: roundIncrement = 0x40;
565: if ( ! roundNearestEven ) {
566: if ( roundingMode == float_round_to_zero ) {
567: roundIncrement = 0;
568: }
569: else {
570: roundIncrement = 0x7F;
571: if ( zSign ) {
572: if ( roundingMode == float_round_up ) roundIncrement = 0;
573: }
574: else {
575: if ( roundingMode == float_round_down ) roundIncrement = 0;
576: }
577: }
578: }
579: roundBits = absZ & 0x7F;
580: absZ = ( absZ + roundIncrement )>>7;
581: absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
582: z = absZ;
583: if ( zSign ) z = - z;
584: z = (int8_t) z;
585: if ( ( absZ>>8 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
586: float_raise( float_flag_invalid, status );
587: return zSign ? (int8_t) 0x80 : 0x7F;
588: }
589: if ( roundBits ) status->float_exception_flags |= float_flag_inexact;
590: return z;
591:
592: }
593: #endif // End of addition for Previous
594:
595: /*----------------------------------------------------------------------------
596: | Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
597: | `absZ1', with binary point between bits 63 and 64 (between the input words),
598: | and returns the properly rounded 64-bit integer corresponding to the input.
599: | If `zSign' is 1, the input is negated before being converted to an integer.
600: | Ordinarily, the fixed-point input is simply rounded to an integer, with
601: | the inexact exception raised if the input cannot be represented exactly as
602: | an integer. However, if the fixed-point input is too large, the invalid
603: | exception is raised and the largest positive or negative integer is
604: | returned.
605: *----------------------------------------------------------------------------*/
606:
607: static int64_t roundAndPackInt64(flag zSign, uint64_t absZ0, uint64_t absZ1,
608: float_status *status)
609: {
610: int8_t roundingMode;
611: flag roundNearestEven, increment;
612: int64_t z;
613:
614: roundingMode = status->float_rounding_mode;
615: roundNearestEven = ( roundingMode == float_round_nearest_even );
616: switch (roundingMode) {
617: case float_round_nearest_even:
618: case float_round_ties_away:
619: increment = ((int64_t) absZ1 < 0);
620: break;
621: case float_round_to_zero:
622: increment = 0;
623: break;
624: case float_round_up:
625: increment = !zSign && absZ1;
626: break;
627: case float_round_down:
628: increment = zSign && absZ1;
629: break;
630: default:
631: abort();
632: }
633: if ( increment ) {
634: ++absZ0;
635: if ( absZ0 == 0 ) goto overflow;
636: absZ0 &= ~ ( ( (uint64_t) ( absZ1<<1 ) == 0 ) & roundNearestEven );
637: }
638: z = absZ0;
639: if ( zSign ) z = - z;
640: if ( z && ( ( z < 0 ) ^ zSign ) ) {
641: overflow:
642: float_raise(float_flag_invalid, status);
643: return
644: zSign ? (int64_t) LIT64( 0x8000000000000000 )
645: : LIT64( 0x7FFFFFFFFFFFFFFF );
646: }
647: if (absZ1) {
648: status->float_exception_flags |= float_flag_inexact;
649: }
650: return z;
651:
652: }
653:
654: /*----------------------------------------------------------------------------
655: | Returns the fraction bits of the single-precision floating-point value `a'.
656: *----------------------------------------------------------------------------*/
657:
658: static inline uint32_t extractFloat32Frac( float32 a )
659: {
660:
661: return float32_val(a) & 0x007FFFFF;
662:
663: }
664:
665: /*----------------------------------------------------------------------------
666: | Returns the exponent bits of the single-precision floating-point value `a'.
667: *----------------------------------------------------------------------------*/
668:
669: static inline int extractFloat32Exp(float32 a)
670: {
671:
672: return ( float32_val(a)>>23 ) & 0xFF;
673:
674: }
675:
676: /*----------------------------------------------------------------------------
677: | Returns the sign bit of the single-precision floating-point value `a'.
678: *----------------------------------------------------------------------------*/
679:
680: static inline flag extractFloat32Sign( float32 a )
681: {
682:
683: return float32_val(a)>>31;
684:
685: }
686:
687: /*----------------------------------------------------------------------------
688: | Normalizes the subnormal single-precision floating-point value represented
689: | by the denormalized significand `aSig'. The normalized exponent and
690: | significand are stored at the locations pointed to by `zExpPtr' and
691: | `zSigPtr', respectively.
692: *----------------------------------------------------------------------------*/
693:
694: static void
695: normalizeFloat32Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr)
696: {
697: int8_t shiftCount;
698:
699: shiftCount = countLeadingZeros32( aSig ) - 8;
700: *zSigPtr = aSig<<shiftCount;
701: *zExpPtr = 1 - shiftCount;
702:
703: }
704:
705: /*----------------------------------------------------------------------------
706: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
707: | single-precision floating-point value, returning the result. After being
708: | shifted into the proper positions, the three fields are simply added
709: | together to form the result. This means that any integer portion of `zSig'
710: | will be added into the exponent. Since a properly normalized significand
711: | will have an integer portion equal to 1, the `zExp' input should be 1 less
712: | than the desired result exponent whenever `zSig' is a complete, normalized
713: | significand.
714: *----------------------------------------------------------------------------*/
715:
716: static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
717: {
718:
719: return make_float32(
720: ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
721:
722: }
723:
724: /*----------------------------------------------------------------------------
725: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
726: | and significand `zSig', and returns the proper single-precision floating-
727: | point value corresponding to the abstract input. Ordinarily, the abstract
728: | value is simply rounded and packed into the single-precision format, with
729: | the inexact exception raised if the abstract input cannot be represented
730: | exactly. However, if the abstract value is too large, the overflow and
731: | inexact exceptions are raised and an infinity or maximal finite value is
732: | returned. If the abstract value is too small, the input value is rounded to
733: | a subnormal number, and the underflow and inexact exceptions are raised if
734: | the abstract input cannot be represented exactly as a subnormal single-
735: | precision floating-point number.
736: | The input significand `zSig' has its binary point between bits 30
737: | and 29, which is 7 bits to the left of the usual location. This shifted
738: | significand must be normalized or smaller. If `zSig' is not normalized,
739: | `zExp' must be 0; in that case, the result returned is a subnormal number,
740: | and it must not require rounding. In the usual case that `zSig' is
741: | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
742: | The handling of underflow and overflow follows the IEC/IEEE Standard for
743: | Binary Floating-Point Arithmetic.
744: *----------------------------------------------------------------------------*/
745:
746: static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig,
747: float_status *status)
748: {
749: int8_t roundingMode;
750: flag roundNearestEven;
751: int8_t roundIncrement, roundBits;
752: flag isTiny;
753:
754: roundingMode = status->float_rounding_mode;
755: roundNearestEven = ( roundingMode == float_round_nearest_even );
756: switch (roundingMode) {
757: case float_round_nearest_even:
758: case float_round_ties_away:
759: roundIncrement = 0x40;
760: break;
761: case float_round_to_zero:
762: roundIncrement = 0;
763: break;
764: case float_round_up:
765: roundIncrement = zSign ? 0 : 0x7f;
766: break;
767: case float_round_down:
768: roundIncrement = zSign ? 0x7f : 0;
769: break;
770: default:
771: abort();
772: break;
773: }
774: roundBits = zSig & 0x7F;
775: if ( 0xFD <= (uint16_t) zExp ) {
776: if ( ( 0xFD < zExp )
777: || ( ( zExp == 0xFD )
778: && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )
779: ) {
780: #ifdef SOFTFLOAT_68K
781: float_raise( float_flag_overflow, status );
782: saveFloat32Internal( zSign, zExp, zSig, status );
783: if ( roundBits ) float_raise( float_flag_inexact, status );
784: #else
785: float_raise(float_flag_overflow | float_flag_inexact, status);
786: #endif
787: return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
788: }
789: if ( zExp < 0 ) {
790: if (status->flush_to_zero) {
791: //float_raise(float_flag_output_denormal, status);
792: return packFloat32(zSign, 0, 0);
793: }
794: isTiny =
795: (status->float_detect_tininess
796: == float_tininess_before_rounding)
797: || ( zExp < -1 )
798: || ( zSig + roundIncrement < 0x80000000 );
799: #ifdef SOFTFLOAT_68K
800: if ( isTiny ) {
801: float_raise( float_flag_underflow, status );
802: saveFloat32Internal( zSign, zExp, zSig, status );
803: }
804: #endif
805: shift32RightJamming( zSig, - zExp, &zSig );
806: zExp = 0;
807: roundBits = zSig & 0x7F;
808: #ifndef SOFTFLOAT_68K
809: if (isTiny && roundBits)
810: float_raise(float_flag_underflow, status);
811: #endif
812: }
813: }
814: if (roundBits) {
815: status->float_exception_flags |= float_flag_inexact;
816: }
817: zSig = ( zSig + roundIncrement )>>7;
818: zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
819: if ( zSig == 0 ) zExp = 0;
820: return packFloat32( zSign, zExp, zSig );
821:
822: }
823:
824: /*----------------------------------------------------------------------------
825: | Returns the fraction bits of the double-precision floating-point value `a'.
826: *----------------------------------------------------------------------------*/
827:
828: static inline uint64_t extractFloat64Frac( float64 a )
829: {
830:
831: return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
832:
833: }
834:
835: /*----------------------------------------------------------------------------
836: | Returns the exponent bits of the double-precision floating-point value `a'.
837: *----------------------------------------------------------------------------*/
838:
839: static inline int extractFloat64Exp(float64 a)
840: {
841:
842: return ( float64_val(a)>>52 ) & 0x7FF;
843:
844: }
845:
846: /*----------------------------------------------------------------------------
847: | Returns the sign bit of the double-precision floating-point value `a'.
848: *----------------------------------------------------------------------------*/
849:
850: static inline flag extractFloat64Sign( float64 a )
851: {
852:
853: return float64_val(a)>>63;
854:
855: }
856:
857: /*----------------------------------------------------------------------------
858: | If `a' is denormal and we are in flush-to-zero mode then set the
859: | input-denormal exception and return zero. Otherwise just return the value.
860: *----------------------------------------------------------------------------*/
861: float64 float64_squash_input_denormal(float64 a, float_status *status)
862: {
863: if (status->flush_inputs_to_zero) {
864: if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
865: //float_raise(float_flag_input_denormal, status);
866: return make_float64(float64_val(a) & (1ULL << 63));
867: }
868: }
869: return a;
870: }
871:
872: /*----------------------------------------------------------------------------
873: | Normalizes the subnormal double-precision floating-point value represented
874: | by the denormalized significand `aSig'. The normalized exponent and
875: | significand are stored at the locations pointed to by `zExpPtr' and
876: | `zSigPtr', respectively.
877: *----------------------------------------------------------------------------*/
878:
879: static void
880: normalizeFloat64Subnormal(uint64_t aSig, int *zExpPtr, uint64_t *zSigPtr)
881: {
882: int8_t shiftCount;
883:
884: shiftCount = countLeadingZeros64( aSig ) - 11;
885: *zSigPtr = aSig<<shiftCount;
886: *zExpPtr = 1 - shiftCount;
887:
888: }
889:
890: /*----------------------------------------------------------------------------
891: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
892: | double-precision floating-point value, returning the result. After being
893: | shifted into the proper positions, the three fields are simply added
894: | together to form the result. This means that any integer portion of `zSig'
895: | will be added into the exponent. Since a properly normalized significand
896: | will have an integer portion equal to 1, the `zExp' input should be 1 less
897: | than the desired result exponent whenever `zSig' is a complete, normalized
898: | significand.
899: *----------------------------------------------------------------------------*/
900:
901: static inline float64 packFloat64(flag zSign, int zExp, uint64_t zSig)
902: {
903:
904: return make_float64(
905: ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig);
906:
907: }
908:
909: /*----------------------------------------------------------------------------
910: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
911: | and significand `zSig', and returns the proper double-precision floating-
912: | point value corresponding to the abstract input. Ordinarily, the abstract
913: | value is simply rounded and packed into the double-precision format, with
914: | the inexact exception raised if the abstract input cannot be represented
915: | exactly. However, if the abstract value is too large, the overflow and
916: | inexact exceptions are raised and an infinity or maximal finite value is
917: | returned. If the abstract value is too small, the input value is rounded to
918: | a subnormal number, and the underflow and inexact exceptions are raised if
919: | the abstract input cannot be represented exactly as a subnormal double-
920: | precision floating-point number.
921: | The input significand `zSig' has its binary point between bits 62
922: | and 61, which is 10 bits to the left of the usual location. This shifted
923: | significand must be normalized or smaller. If `zSig' is not normalized,
924: | `zExp' must be 0; in that case, the result returned is a subnormal number,
925: | and it must not require rounding. In the usual case that `zSig' is
926: | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
927: | The handling of underflow and overflow follows the IEC/IEEE Standard for
928: | Binary Floating-Point Arithmetic.
929: *----------------------------------------------------------------------------*/
930:
931: static float64 roundAndPackFloat64(flag zSign, int zExp, uint64_t zSig,
932: float_status *status)
933: {
934: int8_t roundingMode;
935: flag roundNearestEven;
936: int roundIncrement, roundBits;
937: flag isTiny;
938:
939: roundingMode = status->float_rounding_mode;
940: roundNearestEven = ( roundingMode == float_round_nearest_even );
941: switch (roundingMode) {
942: case float_round_nearest_even:
943: case float_round_ties_away:
944: roundIncrement = 0x200;
945: break;
946: case float_round_to_zero:
947: roundIncrement = 0;
948: break;
949: case float_round_up:
950: roundIncrement = zSign ? 0 : 0x3ff;
951: break;
952: case float_round_down:
953: roundIncrement = zSign ? 0x3ff : 0;
954: break;
955: default:
956: abort();
957: }
958: roundBits = zSig & 0x3FF;
959: if ( 0x7FD <= (uint16_t) zExp ) {
960: if ( ( 0x7FD < zExp )
961: || ( ( zExp == 0x7FD )
962: && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )
963: ) {
964: #ifdef SOFTFLOAT_68K
965: float_raise( float_flag_overflow, status );
966: saveFloat64Internal( zSign, zExp, zSig, status );
967: if ( roundBits ) float_raise( float_flag_inexact, status );
968: #else
969: float_raise(float_flag_overflow | float_flag_inexact, status);
970: #endif
971: return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
972: }
973: if ( zExp < 0 ) {
974: if (status->flush_to_zero) {
975: //float_raise(float_flag_output_denormal, status);
976: return packFloat64(zSign, 0, 0);
977: }
978: isTiny =
979: (status->float_detect_tininess
980: == float_tininess_before_rounding)
981: || ( zExp < -1 )
982: || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
983: #ifdef SOFTFLOAT_68K
984: if ( isTiny ) {
985: float_raise( float_flag_underflow, status );
986: saveFloat64Internal( zSign, zExp, zSig, status );
987: }
988: #endif
989: shift64RightJamming( zSig, - zExp, &zSig );
990: zExp = 0;
991: roundBits = zSig & 0x3FF;
992: #ifndef SOFTFLOAT_68K
993: if (isTiny && roundBits)
994: float_raise(float_flag_underflow, status);
995: #endif
996: }
997: }
998: if (roundBits) {
999: status->float_exception_flags |= float_flag_inexact;
1000: }
1001: zSig = ( zSig + roundIncrement )>>10;
1002: zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
1003: if ( zSig == 0 ) zExp = 0;
1004: return packFloat64( zSign, zExp, zSig );
1005:
1006: }
1007:
1008: /*----------------------------------------------------------------------------
1009: | Returns the fraction bits of the extended double-precision floating-point
1010: | value `a'.
1011: *----------------------------------------------------------------------------*/
1012:
1013: uint64_t extractFloatx80Frac( floatx80 a )
1014: {
1015:
1016: return a.low;
1017:
1018: }
1019:
1020: /*----------------------------------------------------------------------------
1021: | Returns the exponent bits of the extended double-precision floating-point
1022: | value `a'.
1023: *----------------------------------------------------------------------------*/
1024:
1025: int32_t extractFloatx80Exp( floatx80 a )
1026: {
1027:
1028: return a.high & 0x7FFF;
1029:
1030: }
1031:
1032: /*----------------------------------------------------------------------------
1033: | Returns the sign bit of the extended double-precision floating-point value
1034: | `a'.
1035: *----------------------------------------------------------------------------*/
1036:
1037: flag extractFloatx80Sign( floatx80 a )
1038: {
1039:
1040: return a.high>>15;
1041:
1042: }
1043:
1044: /*----------------------------------------------------------------------------
1045: | Normalizes the subnormal extended double-precision floating-point value
1046: | represented by the denormalized significand `aSig'. The normalized exponent
1047: | and significand are stored at the locations pointed to by `zExpPtr' and
1048: | `zSigPtr', respectively.
1049: *----------------------------------------------------------------------------*/
1050:
1051: void normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr )
1052: {
1053: int8_t shiftCount;
1054:
1055: shiftCount = countLeadingZeros64( aSig );
1056: *zSigPtr = aSig<<shiftCount;
1057: #ifdef SOFTFLOAT_68K
1058: *zExpPtr = -shiftCount;
1059: #else
1060: *zExpPtr = 1 - shiftCount;
1061: #endif
1062: }
1063:
1064: /*----------------------------------------------------------------------------
1065: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
1066: | extended double-precision floating-point value, returning the result.
1067: *----------------------------------------------------------------------------*/
1068:
1069: floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
1070: {
1071: floatx80 z;
1072:
1073: z.low = zSig;
1074: z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
1075: return z;
1076:
1077: }
1078:
1079: /*----------------------------------------------------------------------------
1080: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
1081: | and extended significand formed by the concatenation of `zSig0' and `zSig1',
1082: | and returns the proper extended double-precision floating-point value
1083: | corresponding to the abstract input. Ordinarily, the abstract value is
1084: | rounded and packed into the extended double-precision format, with the
1085: | inexact exception raised if the abstract input cannot be represented
1086: | exactly. However, if the abstract value is too large, the overflow and
1087: | inexact exceptions are raised and an infinity or maximal finite value is
1088: | returned. If the abstract value is too small, the input value is rounded to
1089: | a subnormal number, and the underflow and inexact exceptions are raised if
1090: | the abstract input cannot be represented exactly as a subnormal extended
1091: | double-precision floating-point number.
1092: | If `roundingPrecision' is 32 or 64, the result is rounded to the same
1093: | number of bits as single or double precision, respectively. Otherwise, the
1094: | result is rounded to the full precision of the extended double-precision
1095: | format.
1096: | The input significand must be normalized or smaller. If the input
1097: | significand is not normalized, `zExp' must be 0; in that case, the result
1098: | returned is a subnormal number, and it must not require rounding. The
1099: | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
1100: | Floating-Point Arithmetic.
1101: *----------------------------------------------------------------------------*/
1102:
1103: #ifndef SOFTFLOAT_68K
1104: floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
1105: int32_t zExp, uint64_t zSig0, uint64_t zSig1,
1106: float_status *status)
1107: {
1108: int8_t roundingMode;
1109: flag roundNearestEven, increment, isTiny;
1110: int64_t roundIncrement, roundMask, roundBits;
1111:
1112: roundingMode = status->float_rounding_mode;
1113: roundNearestEven = ( roundingMode == float_round_nearest_even );
1114: if ( roundingPrecision == 80 ) goto precision80;
1115: if ( roundingPrecision == 64 ) {
1116: roundIncrement = LIT64( 0x0000000000000400 );
1117: roundMask = LIT64( 0x00000000000007FF );
1118: }
1119: else if ( roundingPrecision == 32 ) {
1120: roundIncrement = LIT64( 0x0000008000000000 );
1121: roundMask = LIT64( 0x000000FFFFFFFFFF );
1122: }
1123: else {
1124: goto precision80;
1125: }
1126: zSig0 |= ( zSig1 != 0 );
1127: switch (roundingMode) {
1128: case float_round_nearest_even:
1129: case float_round_ties_away:
1130: break;
1131: case float_round_to_zero:
1132: roundIncrement = 0;
1133: break;
1134: case float_round_up:
1135: roundIncrement = zSign ? 0 : roundMask;
1136: break;
1137: case float_round_down:
1138: roundIncrement = zSign ? roundMask : 0;
1139: break;
1140: default:
1141: abort();
1142: }
1143: roundBits = zSig0 & roundMask;
1144: #ifdef SOFTFLOAT_68K
1145: if ( 0x7FFE <= (uint32_t) zExp ) {
1146: #else
1147: if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
1148: #endif
1149: if ( ( 0x7FFE < zExp )
1150: || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
1151: ) {
1152: goto overflow;
1153: }
1154: #ifdef SOFTFLOAT_68K
1155: if ( zExp < 0 ) {
1156: #else
1157: if ( zExp <= 0 ) {
1158: #endif
1159: if (status->flush_to_zero) {
1160: //float_raise(float_flag_output_denormal, status);
1161: return packFloatx80(zSign, 0, 0);
1162: }
1163: isTiny =
1164: (status->float_detect_tininess
1165: == float_tininess_before_rounding)
1166: #ifdef SOFTFLOAT_68K
1167: || ( zExp < -1 )
1168: #else
1169: || ( zExp < 0 )
1170: #endif
1171: || ( zSig0 <= zSig0 + roundIncrement );
1172: #ifdef SOFTFLOAT_68K
1173: if ( isTiny ) {
1174: float_raise( float_flag_underflow, status );
1175: saveFloatx80Internal( zSign, zExp, zSig0, zSig1, status );
1176: }
1177: shift64RightJamming( zSig0, -zExp, &zSig0 );
1178: #else
1179: shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
1180: #endif
1181: zExp = 0;
1182: roundBits = zSig0 & roundMask;
1183: #ifdef SOFTFLOAT_68K
1184: if ( isTiny ) float_raise( float_flag_underflow, status );
1185: #else
1186: if (isTiny && roundBits) {
1187: float_raise(float_flag_underflow, status);
1188: }
1189: #endif
1190: if (roundBits) {
1191: status->float_exception_flags |= float_flag_inexact;
1192: }
1193: zSig0 += roundIncrement;
1194: #ifndef SOFTFLOAT_68K
1195: if ( (int64_t) zSig0 < 0 ) zExp = 1;
1196: #endif
1197: roundIncrement = roundMask + 1;
1198: if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
1199: roundMask |= roundIncrement;
1200: }
1201: zSig0 &= ~ roundMask;
1202: return packFloatx80( zSign, zExp, zSig0 );
1203: }
1204: }
1205: if (roundBits) {
1206: status->float_exception_flags |= float_flag_inexact;
1207: }
1208: zSig0 += roundIncrement;
1209: if ( zSig0 < roundIncrement ) {
1210: ++zExp;
1211: zSig0 = LIT64( 0x8000000000000000 );
1212: }
1213: roundIncrement = roundMask + 1;
1214: if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
1215: roundMask |= roundIncrement;
1216: }
1217: zSig0 &= ~ roundMask;
1218: if ( zSig0 == 0 ) zExp = 0;
1219: return packFloatx80( zSign, zExp, zSig0 );
1220: precision80:
1221: switch (roundingMode) {
1222: case float_round_nearest_even:
1223: case float_round_ties_away:
1224: increment = ((int64_t)zSig1 < 0);
1225: break;
1226: case float_round_to_zero:
1227: increment = 0;
1228: break;
1229: case float_round_up:
1230: increment = !zSign && zSig1;
1231: break;
1232: case float_round_down:
1233: increment = zSign && zSig1;
1234: break;
1235: default:
1236: abort();
1237: }
1238: #ifdef SOFTFLOAT_68K
1239: if ( 0x7FFE <= (uint32_t) zExp ) {
1240: #else
1241: if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
1242: #endif
1243: if ( ( 0x7FFE < zExp )
1244: || ( ( zExp == 0x7FFE )
1245: && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
1246: && increment
1247: )
1248: ) {
1249: roundMask = 0;
1250: overflow:
1251: #ifndef SOFTFLOAT_68K
1252: float_raise(float_flag_overflow | float_flag_inexact, status);
1253: #else
1254: float_raise( float_flag_overflow, status );
1255: saveFloatx80Internal( zSign, zExp, zSig0, zSig1, status );
1256: if ( ( zSig0 & roundMask ) || zSig1 ) float_raise( float_flag_inexact, status );
1257: #endif
1258: if ( ( roundingMode == float_round_to_zero )
1259: || ( zSign && ( roundingMode == float_round_up ) )
1260: || ( ! zSign && ( roundingMode == float_round_down ) )
1261: ) {
1262: return packFloatx80( zSign, 0x7FFE, ~ roundMask );
1263: }
1264: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
1265: }
1266: #ifdef SOFTFLOAT_68K
1267: if ( zExp < 0 ) {
1268: #else
1269: if ( zExp <= 0 ) {
1270: #endif
1271: isTiny =
1272: (status->float_detect_tininess
1273: == float_tininess_before_rounding)
1274: #ifdef SOFTFLOAT_68K
1275: || ( zExp < -1 )
1276: #else
1277: || ( zExp < 0 )
1278: #endif
1279: || ! increment
1280: || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
1281: #ifdef SOFTFLOAT_68K
1282: if ( isTiny ) {
1283: float_raise( float_flag_underflow, status );
1284: saveFloatx80Internal( zSign, zExp, zSig0, zSig1, status );
1285: }
1286: shift64ExtraRightJamming( zSig0, zSig1, -zExp, &zSig0, &zSig1 );
1287: #else
1288: shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
1289: #endif
1290: zExp = 0;
1291: #ifndef SOFTFLOAT_68K
1292: if ( isTiny && zSig1 ) float_raise( float_flag_underflow, status );
1293: #endif
1294: if (zSig1) float_raise(float_flag_inexact, status);
1295: switch (roundingMode) {
1296: case float_round_nearest_even:
1297: case float_round_ties_away:
1298: increment = ((int64_t)zSig1 < 0);
1299: break;
1300: case float_round_to_zero:
1301: increment = 0;
1302: break;
1303: case float_round_up:
1304: increment = !zSign && zSig1;
1305: break;
1306: case float_round_down:
1307: increment = zSign && zSig1;
1308: break;
1309: default:
1310: abort();
1311: }
1312: if ( increment ) {
1313: ++zSig0;
1314: zSig0 &=
1315: ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
1316: #ifndef SOFTFLOAT_68K
1317: if ( (int64_t) zSig0 < 0 ) zExp = 1;
1318: #endif
1319: }
1320: return packFloatx80( zSign, zExp, zSig0 );
1321: }
1322: }
1323: if (zSig1) {
1324: status->float_exception_flags |= float_flag_inexact;
1325: }
1326: if ( increment ) {
1327: ++zSig0;
1328: if ( zSig0 == 0 ) {
1329: ++zExp;
1330: zSig0 = LIT64( 0x8000000000000000 );
1331: }
1332: else {
1333: zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
1334: }
1335: }
1336: else {
1337: if ( zSig0 == 0 ) zExp = 0;
1338: }
1339: return packFloatx80( zSign, zExp, zSig0 );
1340:
1341: }
1342:
1343: #else // SOFTFLOAT_68K
1344:
1345: floatx80 roundAndPackFloatx80( int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status )
1346: {
1347: int8_t roundingMode;
1348: flag roundNearestEven, increment;
1349: int64_t roundIncrement, roundMask, roundBits;
1350: int32_t expOffset;
1351:
1352: roundingMode = status->float_rounding_mode;
1353: roundNearestEven = ( roundingMode == float_round_nearest_even );
1354: if ( roundingPrecision == 80 ) goto precision80;
1355: if ( roundingPrecision == 64 ) {
1356: roundIncrement = LIT64( 0x0000000000000400 );
1357: roundMask = LIT64( 0x00000000000007FF );
1358: expOffset = 0x3C00;
1359: } else if ( roundingPrecision == 32 ) {
1360: roundIncrement = LIT64( 0x0000008000000000 );
1361: roundMask = LIT64( 0x000000FFFFFFFFFF );
1362: expOffset = 0x3F80;
1363: } else {
1364: goto precision80;
1365: }
1366: zSig0 |= ( zSig1 != 0 );
1367: if ( ! roundNearestEven ) {
1368: if ( roundingMode == float_round_to_zero ) {
1369: roundIncrement = 0;
1370: } else {
1371: roundIncrement = roundMask;
1372: if ( zSign ) {
1373: if ( roundingMode == float_round_up ) roundIncrement = 0;
1374: } else {
1375: if ( roundingMode == float_round_down ) roundIncrement = 0;
1376: }
1377: }
1378: }
1379: roundBits = zSig0 & roundMask;
1380: if ( ( ( 0x7FFE - expOffset ) < zExp ) ||
1381: ( ( zExp == ( 0x7FFE - expOffset ) ) && ( zSig0 + roundIncrement < zSig0 ) ) ) {
1382: float_raise( float_flag_overflow, status );
1383: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1384: if ( zSig0 & roundMask ) float_raise( float_flag_inexact, status );
1385: if ( ( roundingMode == float_round_to_zero )
1386: || ( zSign && ( roundingMode == float_round_up ) )
1387: || ( ! zSign && ( roundingMode == float_round_down ) )
1388: ) {
1389: return packFloatx80( zSign, 0x7FFE - expOffset, ~ roundMask );
1390: }
1391: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
1392: }
1393: if ( zExp < ( expOffset + 1 ) ) {
1394: float_raise( float_flag_underflow, status );
1395: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1396: shift64RightJamming( zSig0, -( zExp - ( expOffset + 1 ) ), &zSig0 );
1397: zExp = expOffset + 1;
1398: roundBits = zSig0 & roundMask;
1399: if ( roundBits ) float_raise( float_flag_inexact, status );
1400: zSig0 += roundIncrement;
1401: roundIncrement = roundMask + 1;
1402: if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
1403: roundMask |= roundIncrement;
1404: }
1405: zSig0 &= ~ roundMask;
1406: return packFloatx80( zSign, zExp, zSig0 );
1407: }
1408: if ( roundBits ) {
1409: float_raise( float_flag_inexact, status );
1410: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status);
1411: }
1412: zSig0 += roundIncrement;
1413: if ( zSig0 < roundIncrement ) {
1414: ++zExp;
1415: zSig0 = LIT64( 0x8000000000000000 );
1416: }
1417: roundIncrement = roundMask + 1;
1418: if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
1419: roundMask |= roundIncrement;
1420: }
1421: zSig0 &= ~ roundMask;
1422: if ( zSig0 == 0 ) zExp = 0;
1423: return packFloatx80( zSign, zExp, zSig0 );
1424: precision80:
1425: increment = ( (int64_t) zSig1 < 0 );
1426: if ( ! roundNearestEven ) {
1427: if ( roundingMode == float_round_to_zero ) {
1428: increment = 0;
1429: } else {
1430: if ( zSign ) {
1431: increment = ( roundingMode == float_round_down ) && zSig1;
1432: } else {
1433: increment = ( roundingMode == float_round_up ) && zSig1;
1434: }
1435: }
1436: }
1437: if ( 0x7FFE <= (uint32_t) zExp ) {
1438: if ( ( 0x7FFE < zExp ) ||
1439: ( ( zExp == 0x7FFE ) && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) ) && increment )
1440: ) {
1441: roundMask = 0;
1442: float_raise( float_flag_overflow, status );
1443: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1444: if ( ( zSig0 & roundMask ) || zSig1 ) float_raise( float_flag_inexact, status );
1445: if ( ( roundingMode == float_round_to_zero )
1446: || ( zSign && ( roundingMode == float_round_up ) )
1447: || ( ! zSign && ( roundingMode == float_round_down ) )
1448: ) {
1449: return packFloatx80( zSign, 0x7FFE, ~ roundMask );
1450: }
1451: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
1452: }
1453: if ( zExp < 0 ) {
1454: float_raise( float_flag_underflow, status );
1455: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status);
1456: shift64ExtraRightJamming( zSig0, zSig1, -zExp, &zSig0, &zSig1 );
1457: zExp = 0;
1458: if ( zSig1 ) float_raise( float_flag_inexact, status );
1459: if ( roundNearestEven ) {
1460: increment = ( (int64_t) zSig1 < 0 );
1461: } else {
1462: if ( zSign ) {
1463: increment = ( roundingMode == float_round_down ) && zSig1;
1464: } else {
1465: increment = ( roundingMode == float_round_up ) && zSig1;
1466: }
1467: }
1468: if ( increment ) {
1469: ++zSig0;
1470: zSig0 &=
1471: ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
1472: }
1473: return packFloatx80( zSign, zExp, zSig0 );
1474: }
1475: }
1476: if ( zSig1 ) {
1477: float_raise( float_flag_inexact, status );
1478: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1479: }
1480: if ( increment ) {
1481: ++zSig0;
1482: if ( zSig0 == 0 ) {
1483: ++zExp;
1484: zSig0 = LIT64( 0x8000000000000000 );
1485: } else {
1486: zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
1487: }
1488: } else {
1489: if ( zSig0 == 0 ) zExp = 0;
1490: }
1491: return packFloatx80( zSign, zExp, zSig0 );
1492:
1493: }
1494:
1495: #endif
1496:
1497: #ifdef SOFTFLOAT_68K // 21-01-2017: Added for Previous
1498: floatx80 roundSigAndPackFloatx80( int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status )
1499: {
1500: int8_t roundingMode;
1501: flag roundNearestEven, isTiny;
1502: int64_t roundIncrement, roundMask, roundBits;
1503:
1504: roundingMode = status->float_rounding_mode;
1505: roundNearestEven = ( roundingMode == float_round_nearest_even );
1506: if ( roundingPrecision == 32 ) {
1507: roundIncrement = LIT64( 0x0000008000000000 );
1508: roundMask = LIT64( 0x000000FFFFFFFFFF );
1509: } else if ( roundingPrecision == 64 ) {
1510: roundIncrement = LIT64( 0x0000000000000400 );
1511: roundMask = LIT64( 0x00000000000007FF );
1512: } else {
1513: return roundAndPackFloatx80( 80, zSign, zExp, zSig0, zSig1, status );
1514: }
1515: zSig0 |= ( zSig1 != 0 );
1516: if ( ! roundNearestEven ) {
1517: if ( roundingMode == float_round_to_zero ) {
1518: roundIncrement = 0;
1519: }
1520: else {
1521: roundIncrement = roundMask;
1522: if ( zSign ) {
1523: if ( roundingMode == float_round_up ) roundIncrement = 0;
1524: }
1525: else {
1526: if ( roundingMode == float_round_down ) roundIncrement = 0;
1527: }
1528: }
1529: }
1530: roundBits = zSig0 & roundMask;
1531:
1532: if ( 0x7FFE <= (uint32_t) zExp ) {
1533: if ( ( 0x7FFE < zExp )
1534: || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
1535: ) {
1536: float_raise( float_flag_overflow, status );
1537: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status);
1538: if ( zSig0 & roundMask ) float_raise( float_flag_inexact, status );
1539: if ( ( roundingMode == float_round_to_zero )
1540: || ( zSign && ( roundingMode == float_round_up ) )
1541: || ( ! zSign && ( roundingMode == float_round_down ) )
1542: ) {
1543: return packFloatx80( zSign, 0x7FFE, LIT64( 0xFFFFFFFFFFFFFFFF ) );
1544: }
1545: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
1546: }
1547:
1548: if ( zExp < 0 ) {
1549: isTiny =
1550: ( status->float_detect_tininess == float_tininess_before_rounding )
1551: || ( zExp < -1 )
1552: || ( zSig0 <= zSig0 + roundIncrement );
1553: if ( isTiny ) {
1554: float_raise( float_flag_underflow, status );
1555: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1556: }
1557: shift64RightJamming( zSig0, -zExp, &zSig0 );
1558: zExp = 0;
1559: roundBits = zSig0 & roundMask;
1560: if ( roundBits ) float_raise ( float_flag_inexact, status );
1561: zSig0 += roundIncrement;
1562: if ( roundNearestEven && ( roundBits == roundIncrement ) ) {
1563: roundMask |= roundIncrement<<1;
1564: }
1565: zSig0 &= ~roundMask;
1566: return packFloatx80( zSign, zExp, zSig0 );
1567: }
1568: }
1569: if ( roundBits ) {
1570: float_raise( float_flag_inexact, status );
1571: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, status );
1572: }
1573: zSig0 += roundIncrement;
1574: if ( zSig0 < roundIncrement ) {
1575: ++zExp;
1576: zSig0 = LIT64( 0x8000000000000000 );
1577: }
1578: roundIncrement = roundMask + 1;
1579: if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
1580: roundMask |= roundIncrement;
1581: }
1582: zSig0 &= ~ roundMask;
1583: if ( zSig0 == 0 ) zExp = 0;
1584: return packFloatx80( zSign, zExp, zSig0 );
1585:
1586: }
1587: #endif // End of Addition for Previous
1588:
1589:
1590: /*----------------------------------------------------------------------------
1591: | Takes an abstract floating-point value having sign `zSign', exponent
1592: | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
1593: | and returns the proper extended double-precision floating-point value
1594: | corresponding to the abstract input. This routine is just like
1595: | `roundAndPackFloatx80' except that the input significand does not have to be
1596: | normalized.
1597: *----------------------------------------------------------------------------*/
1598:
1599: static floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
1600: flag zSign, int32_t zExp,
1601: uint64_t zSig0, uint64_t zSig1,
1602: float_status *status)
1603: {
1604: int8_t shiftCount;
1605:
1606: if ( zSig0 == 0 ) {
1607: zSig0 = zSig1;
1608: zSig1 = 0;
1609: zExp -= 64;
1610: }
1611: shiftCount = countLeadingZeros64( zSig0 );
1612: shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
1613: zExp -= shiftCount;
1614: return roundAndPackFloatx80(roundingPrecision, zSign, zExp,
1615: zSig0, zSig1, status);
1616:
1617: }
1618:
1619: /*----------------------------------------------------------------------------
1620: | Returns the result of converting the 32-bit two's complement integer `a'
1621: | to the extended double-precision floating-point format. The conversion
1622: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1623: | Arithmetic.
1624: *----------------------------------------------------------------------------*/
1625:
1626: floatx80 int32_to_floatx80(int32_t a)
1627: {
1628: flag zSign;
1629: uint32_t absA;
1630: int8_t shiftCount;
1631: uint64_t zSig;
1632:
1633: if ( a == 0 ) return packFloatx80( 0, 0, 0 );
1634: zSign = ( a < 0 );
1635: absA = zSign ? - a : a;
1636: shiftCount = countLeadingZeros32( absA ) + 32;
1637: zSig = absA;
1638: return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
1639:
1640: }
1641:
1642: /*----------------------------------------------------------------------------
1643: | Returns the result of converting the single-precision floating-point value
1644: | `a' to the extended double-precision floating-point format. The conversion
1645: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1646: | Arithmetic.
1647: *----------------------------------------------------------------------------*/
1648:
1649: floatx80 float32_to_floatx80(float32 a, float_status *status)
1650: {
1651: flag aSign;
1652: int aExp;
1653: uint32_t aSig;
1654:
1655: aSig = extractFloat32Frac( a );
1656: aExp = extractFloat32Exp( a );
1657: aSign = extractFloat32Sign( a );
1658: if ( aExp == 0xFF ) {
1659: if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a, status ), status );
1660: return packFloatx80( aSign, 0x7FFF, floatx80_default_infinity_low );
1661: }
1662: if ( aExp == 0 ) {
1663: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1664: normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1665: }
1666: aSig |= 0x00800000;
1667: return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 );
1668:
1669: }
1670:
1671: #ifdef SOFTFLOAT_68K // 31-12-2016: Added for Previous
1672: floatx80 float32_to_floatx80_allowunnormal(float32 a , float_status *status)
1673: {
1674: flag aSign;
1675: int16_t aExp;
1676: uint32_t aSig;
1677:
1678: aSig = extractFloat32Frac(a);
1679: aExp = extractFloat32Exp(a);
1680: aSign = extractFloat32Sign(a);
1681: if (aExp == 0xFF) {
1682: return packFloatx80( aSign, 0x7FFF, ( (uint64_t) aSig )<<40 );
1683: }
1684: if (aExp == 0) {
1685: if (aSig == 0) return packFloatx80(aSign, 0, 0);
1686: return packFloatx80(aSign, 0x3F81, ((uint64_t) aSig) << 40);
1687: }
1688: aSig |= 0x00800000;
1689: return packFloatx80(aSign, aExp + 0x3F80, ((uint64_t)aSig) << 40);
1690:
1691: }
1692: #endif // end of addition for Previous
1693:
1694: /*----------------------------------------------------------------------------
1695: | Returns the result of converting the double-precision floating-point value
1696: | `a' to the extended double-precision floating-point format. The conversion
1697: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1698: | Arithmetic.
1699: *----------------------------------------------------------------------------*/
1700:
1701: floatx80 float64_to_floatx80(float64 a, float_status *status)
1702: {
1703: flag aSign;
1704: int aExp;
1705: uint64_t aSig;
1706:
1707: aSig = extractFloat64Frac( a );
1708: aExp = extractFloat64Exp( a );
1709: aSign = extractFloat64Sign( a );
1710: if ( aExp == 0x7FF ) {
1711: if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a, status ), status );
1712: return packFloatx80( aSign, 0x7FFF, floatx80_default_infinity_low );
1713: }
1714: if ( aExp == 0 ) {
1715: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1716: normalizeFloat64Subnormal( aSig, &aExp, &aSig );
1717: }
1718: return
1719: packFloatx80(
1720: aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
1721:
1722: }
1723:
1724: #ifdef SOFTFLOAT_68K // 31-12-2016: Added for Previous
1725: floatx80 float64_to_floatx80_allowunnormal( float64 a, float_status *status )
1726: {
1727: flag aSign;
1728: int16_t aExp;
1729: uint64_t aSig;
1730:
1731: aSig = extractFloat64Frac( a );
1732: aExp = extractFloat64Exp( a );
1733: aSign = extractFloat64Sign( a );
1734: if ( aExp == 0x7FF ) {
1735: return packFloatx80( aSign, 0x7FFF, aSig<<11 );
1736: }
1737: if ( aExp == 0 ) {
1738: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1739: return packFloatx80( aSign, 0x3C01, aSig<<11 );
1740: }
1741: return
1742: packFloatx80(
1743: aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
1744:
1745: }
1746: #endif // end of addition for Previous
1747:
1748: /*----------------------------------------------------------------------------
1749: | Returns the result of converting the extended double-precision floating-
1750: | point value `a' to the 32-bit two's complement integer format. The
1751: | conversion is performed according to the IEC/IEEE Standard for Binary
1752: | Floating-Point Arithmetic---which means in particular that the conversion
1753: | is rounded according to the current rounding mode. If `a' is a NaN, the
1754: | largest positive integer is returned. Otherwise, if the conversion
1755: | overflows, the largest integer with the same sign as `a' is returned.
1756: *----------------------------------------------------------------------------*/
1757:
1758: int32_t floatx80_to_int32(floatx80 a, float_status *status)
1759: {
1760: flag aSign;
1761: int32_t aExp, shiftCount;
1762: uint64_t aSig;
1763:
1764: aSig = extractFloatx80Frac( a );
1765: aExp = extractFloatx80Exp( a );
1766: aSign = extractFloatx80Sign( a );
1767: #ifdef SOFTFLOAT_68K
1768: if ( aExp == 0x7FFF ) {
1769: if ( (uint64_t) ( aSig<<1 ) ) {
1770: a = propagateFloatx80NaNOneArg( a, status );
1771: if ( a.low == aSig ) float_raise( float_flag_invalid, status );
1772: return (int32_t)(a.low>>32);
1773: }
1774: float_raise( float_flag_invalid, status );
1775: return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
1776: }
1777: #else
1778: if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
1779: #endif
1780: shiftCount = 0x4037 - aExp;
1781: if ( shiftCount <= 0 ) shiftCount = 1;
1782: shift64RightJamming( aSig, shiftCount, &aSig );
1783: return roundAndPackInt32(aSign, aSig, status);
1784:
1785: }
1786:
1787: #ifdef SOFTFLOAT_68K // 30-01-2017: Addition for Previous
1788: int16_t floatx80_to_int16( floatx80 a, float_status *status)
1789: {
1790: flag aSign;
1791: int32_t aExp, shiftCount;
1792: uint64_t aSig;
1793:
1794: aSig = extractFloatx80Frac( a );
1795: aExp = extractFloatx80Exp( a );
1796: aSign = extractFloatx80Sign( a );
1797: if ( aExp == 0x7FFF ) {
1798: float_raise( float_flag_invalid, status );
1799: if ( (uint64_t) ( aSig<<1 ) ) {
1800: a = propagateFloatx80NaNOneArg( a, status );
1801: if ( a.low == aSig ) float_raise( float_flag_invalid, status );
1802: return (int16_t)(a.low>>48);
1803: }
1804: return aSign ? (int16_t) 0x8000 : 0x7FFF;
1805: }
1806: shiftCount = 0x4037 - aExp;
1807: if ( shiftCount <= 0 ) shiftCount = 1;
1808: shift64RightJamming( aSig, shiftCount, &aSig );
1809: return roundAndPackInt16( aSign, aSig, status );
1810:
1811: }
1812: int8_t floatx80_to_int8( floatx80 a, float_status *status)
1813: {
1814: flag aSign;
1815: int32_t aExp, shiftCount;
1816: uint64_t aSig;
1817:
1818: aSig = extractFloatx80Frac( a );
1819: aExp = extractFloatx80Exp( a );
1820: aSign = extractFloatx80Sign( a );
1821: if ( aExp == 0x7FFF ) {
1822: if ( (uint64_t) ( aSig<<1 ) ) {
1823: a = propagateFloatx80NaNOneArg( a, status );
1824: if ( a.low == aSig ) float_raise( float_flag_invalid, status );
1825: return (int8_t)(a.low>>56);
1826: }
1827: float_raise( float_flag_invalid, status );
1828: return aSign ? (int8_t) 0x80 : 0x7F;
1829: }
1830: shiftCount = 0x4037 - aExp;
1831: if ( shiftCount <= 0 ) shiftCount = 1;
1832: shift64RightJamming( aSig, shiftCount, &aSig );
1833: return roundAndPackInt8( aSign, aSig, status );
1834:
1835: }
1836: #endif // End of addition for Previous
1837:
1838:
1839: /*----------------------------------------------------------------------------
1840: | Returns the result of converting the extended double-precision floating-
1841: | point value `a' to the 32-bit two's complement integer format. The
1842: | conversion is performed according to the IEC/IEEE Standard for Binary
1843: | Floating-Point Arithmetic, except that the conversion is always rounded
1844: | toward zero. If `a' is a NaN, the largest positive integer is returned.
1845: | Otherwise, if the conversion overflows, the largest integer with the same
1846: | sign as `a' is returned.
1847: *----------------------------------------------------------------------------*/
1848:
1849: int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *status)
1850: {
1851: flag aSign;
1852: int32_t aExp, shiftCount;
1853: uint64_t aSig, savedASig;
1854: int32_t z;
1855:
1856: if (floatx80_invalid_encoding(a)) {
1857: float_raise(float_flag_invalid, status);
1858: return 1 << 31;
1859: }
1860: aSig = extractFloatx80Frac( a );
1861: aExp = extractFloatx80Exp( a );
1862: aSign = extractFloatx80Sign( a );
1863: if ( 0x401E < aExp ) {
1864: if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
1865: goto invalid;
1866: }
1867: else if ( aExp < 0x3FFF ) {
1868: if (aExp || aSig) {
1869: status->float_exception_flags |= float_flag_inexact;
1870: }
1871: return 0;
1872: }
1873: shiftCount = 0x403E - aExp;
1874: savedASig = aSig;
1875: aSig >>= shiftCount;
1876: z = aSig;
1877: if ( aSign ) z = - z;
1878: if ( ( z < 0 ) ^ aSign ) {
1879: invalid:
1880: float_raise(float_flag_invalid, status);
1881: return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
1882: }
1883: if ( ( aSig<<shiftCount ) != savedASig ) {
1884: status->float_exception_flags |= float_flag_inexact;
1885: }
1886: return z;
1887:
1888: }
1889:
1890: /*----------------------------------------------------------------------------
1891: | Returns the result of converting the extended double-precision floating-
1892: | point value `a' to the 64-bit two's complement integer format. The
1893: | conversion is performed according to the IEC/IEEE Standard for Binary
1894: | Floating-Point Arithmetic---which means in particular that the conversion
1895: | is rounded according to the current rounding mode. If `a' is a NaN,
1896: | the largest positive integer is returned. Otherwise, if the conversion
1897: | overflows, the largest integer with the same sign as `a' is returned.
1898: *----------------------------------------------------------------------------*/
1899:
1900: int64_t floatx80_to_int64(floatx80 a, float_status *status)
1901: {
1902: flag aSign;
1903: int32_t aExp, shiftCount;
1904: uint64_t aSig, aSigExtra;
1905:
1906: if (floatx80_invalid_encoding(a)) {
1907: float_raise(float_flag_invalid, status);
1908: return 1ULL << 63;
1909: }
1910: aSig = extractFloatx80Frac( a );
1911: aExp = extractFloatx80Exp( a );
1912: aSign = extractFloatx80Sign( a );
1913: shiftCount = 0x403E - aExp;
1914: if ( shiftCount <= 0 ) {
1915: if ( shiftCount ) {
1916: float_raise(float_flag_invalid, status);
1917: if ( ! aSign
1918: || ( ( aExp == 0x7FFF )
1919: && ( aSig != LIT64( 0x8000000000000000 ) ) )
1920: ) {
1921: return LIT64( 0x7FFFFFFFFFFFFFFF );
1922: }
1923: return (int64_t) LIT64( 0x8000000000000000 );
1924: }
1925: aSigExtra = 0;
1926: }
1927: else {
1928: shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
1929: }
1930: return roundAndPackInt64(aSign, aSig, aSigExtra, status);
1931:
1932: }
1933:
1934: /*----------------------------------------------------------------------------
1935: | Returns the result of converting the extended double-precision floating-
1936: | point value `a' to the single-precision floating-point format. The
1937: | conversion is performed according to the IEC/IEEE Standard for Binary
1938: | Floating-Point Arithmetic.
1939: *----------------------------------------------------------------------------*/
1940:
1941: float32 floatx80_to_float32(floatx80 a, float_status *status)
1942: {
1943: flag aSign;
1944: int32_t aExp;
1945: uint64_t aSig;
1946:
1947: aSig = extractFloatx80Frac( a );
1948: aExp = extractFloatx80Exp( a );
1949: aSign = extractFloatx80Sign( a );
1950: if ( aExp == 0x7FFF ) {
1951: if ( (uint64_t) ( aSig<<1 ) ) {
1952: return commonNaNToFloat32(floatx80ToCommonNaN(a, status));
1953: }
1954: return packFloat32( aSign, 0xFF, 0 );
1955: }
1956: #ifdef SOFTFLOAT_68K
1957: if ( aExp == 0 ) {
1958: if ( aSig == 0) return packFloat32( aSign, 0, 0 );
1959: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
1960: }
1961: shift64RightJamming( aSig, 33, &aSig );
1962: aExp -= 0x3F81;
1963: #else
1964: shift64RightJamming( aSig, 33, &aSig );
1965: if ( aExp || aSig ) aExp -= 0x3F81;
1966: #endif
1967: return roundAndPackFloat32(aSign, aExp, aSig, status);
1968:
1969: }
1970:
1971: /*----------------------------------------------------------------------------
1972: | Returns the result of converting the extended double-precision floating-
1973: | point value `a' to the double-precision floating-point format. The
1974: | conversion is performed according to the IEC/IEEE Standard for Binary
1975: | Floating-Point Arithmetic.
1976: *----------------------------------------------------------------------------*/
1977:
1978: float64 floatx80_to_float64(floatx80 a, float_status *status)
1979: {
1980: flag aSign;
1981: int32_t aExp;
1982: uint64_t aSig, zSig;
1983:
1984: aSig = extractFloatx80Frac( a );
1985: aExp = extractFloatx80Exp( a );
1986: aSign = extractFloatx80Sign( a );
1987: if ( aExp == 0x7FFF ) {
1988: if ( (uint64_t) ( aSig<<1 ) ) {
1989: return commonNaNToFloat64(floatx80ToCommonNaN(a, status), status);
1990: }
1991: return packFloat64( aSign, 0x7FF, 0 );
1992: }
1993: #ifdef SOFTFLOAT_68K
1994: if ( aExp == 0 ) {
1995: if ( aSig == 0) return packFloat64( aSign, 0, 0 );
1996: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
1997: }
1998: shift64RightJamming( aSig, 1, &zSig );
1999: aExp -= 0x3C01;
2000: #else
2001: shift64RightJamming( aSig, 1, &zSig );
2002: if ( aExp || aSig ) aExp -= 0x3C01;
2003: #endif
2004: return roundAndPackFloat64(aSign, aExp, zSig, status);
2005:
2006: }
2007:
2008: #ifdef SOFTFLOAT_68K // 31-01-2017
2009: /*----------------------------------------------------------------------------
2010: | Returns the result of converting the extended double-precision floating-
2011: | point value `a' to the extended double-precision floating-point format.
2012: | The conversion is performed according to the IEC/IEEE Standard for Binary
2013: | Floating-Point Arithmetic.
2014: *----------------------------------------------------------------------------*/
2015:
2016: floatx80 floatx80_to_floatx80( floatx80 a, float_status *status )
2017: {
2018: flag aSign;
2019: int32_t aExp;
2020: uint64_t aSig;
2021:
2022: aSig = extractFloatx80Frac( a );
2023: aExp = extractFloatx80Exp( a );
2024: aSign = extractFloatx80Sign( a );
2025:
2026: if ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) {
2027: return propagateFloatx80NaNOneArg( a, status );
2028: }
2029: if ( aExp == 0 && aSig != 0 ) {
2030: return normalizeRoundAndPackFloatx80( status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
2031: }
2032: return a;
2033:
2034: }
2035: #endif
2036:
2037: #ifdef SOFTFLOAT_68K // 30-01-2016: Added for Previous
2038: floatx80 floatx80_round32( floatx80 a, float_status *status )
2039: {
2040: flag aSign;
2041: int32_t aExp;
2042: uint64_t aSig;
2043:
2044: aSig = extractFloatx80Frac( a );
2045: aExp = extractFloatx80Exp( a );
2046: aSign = extractFloatx80Sign( a );
2047:
2048: if ( aExp == 0x7FFF || aSig == 0 ) {
2049: return a;
2050: }
2051: if ( aExp == 0 ) {
2052: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2053: }
2054:
2055: return roundSigAndPackFloatx80( 32, aSign, aExp, aSig, 0, status );
2056: }
2057:
2058: floatx80 floatx80_round64( floatx80 a, float_status *status )
2059: {
2060: flag aSign;
2061: int32_t aExp;
2062: uint64_t aSig;
2063:
2064: aSig = extractFloatx80Frac( a );
2065: aExp = extractFloatx80Exp( a );
2066: aSign = extractFloatx80Sign( a );
2067:
2068: if ( aExp == 0x7FFF || aSig == 0 ) {
2069: return a;
2070: }
2071: if ( aExp == 0 ) {
2072: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2073: }
2074:
2075: return roundSigAndPackFloatx80( 64, aSign, aExp, aSig, 0, status );
2076: }
2077:
2078: floatx80 floatx80_round_to_float32( floatx80 a, float_status *status )
2079: {
2080: flag aSign;
2081: int32_t aExp;
2082: uint64_t aSig;
2083:
2084: aSign = extractFloatx80Sign( a );
2085: aSig = extractFloatx80Frac( a );
2086: aExp = extractFloatx80Exp( a );
2087:
2088: if ( aExp == 0x7FFF ) {
2089: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status );
2090: return a;
2091: }
2092: if ( aExp == 0 ) {
2093: if ( aSig == 0 ) return a;
2094: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2095: }
2096:
2097: return roundAndPackFloatx80( 32, aSign, aExp, aSig, 0, status );
2098: }
2099:
2100: floatx80 floatx80_round_to_float64( floatx80 a, float_status *status )
2101: {
2102: flag aSign;
2103: int32_t aExp;
2104: uint64_t aSig;
2105:
2106: aSign = extractFloatx80Sign( a );
2107: aSig = extractFloatx80Frac( a );
2108: aExp = extractFloatx80Exp( a );
2109:
2110: if ( aExp == 0x7FFF ) {
2111: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status );
2112: return a;
2113: }
2114: if ( aExp == 0 ) {
2115: if ( aSig == 0 ) return a;
2116: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2117: }
2118:
2119: return roundAndPackFloatx80( 64, aSign, aExp, aSig, 0, status );
2120: }
2121:
2122:
2123: floatx80 floatx80_normalize( floatx80 a )
2124: {
2125: flag aSign;
2126: int16_t aExp;
2127: uint64_t aSig;
2128: int8_t shiftCount;
2129:
2130: aSig = extractFloatx80Frac( a );
2131: aExp = extractFloatx80Exp( a );
2132: aSign = extractFloatx80Sign( a );
2133:
2134: if ( aExp == 0x7FFF || aExp == 0 ) return a;
2135: if ( aSig == 0 ) return packFloatx80(aSign, 0, 0);
2136:
2137: shiftCount = countLeadingZeros64( aSig );
2138:
2139: if ( shiftCount > aExp ) shiftCount = aExp;
2140:
2141: aExp -= shiftCount;
2142: aSig <<= shiftCount;
2143:
2144: return packFloatx80( aSign, aExp, aSig );
2145: }
2146: #endif // end of addition for Previous
2147:
2148: /*----------------------------------------------------------------------------
2149: | Rounds the extended double-precision floating-point value `a' to an integer,
2150: | and returns the result as an extended quadruple-precision floating-point
2151: | value. The operation is performed according to the IEC/IEEE Standard for
2152: | Binary Floating-Point Arithmetic.
2153: *----------------------------------------------------------------------------*/
2154:
2155: floatx80 floatx80_round_to_int(floatx80 a, float_status *status)
2156: {
2157: flag aSign;
2158: int32_t aExp;
2159: uint64_t lastBitMask, roundBitsMask;
2160: floatx80 z;
2161:
2162: if (floatx80_invalid_encoding(a)) {
2163: float_raise(float_flag_invalid, status);
2164: return floatx80_default_nan(status);
2165: }
2166: aExp = extractFloatx80Exp( a );
2167: if ( 0x403E <= aExp ) {
2168: if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
2169: return propagateFloatx80NaNOneArg(a, status);
2170: }
2171: return a;
2172: }
2173: if ( aExp < 0x3FFF ) {
2174: if ( ( aExp == 0 )
2175: #ifdef SOFTFLOAT_68K
2176: && ( (uint64_t) extractFloatx80Frac( a ) == 0 ) ) {
2177: #else
2178: && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
2179: #endif
2180: return a;
2181: }
2182: status->float_exception_flags |= float_flag_inexact;
2183: aSign = extractFloatx80Sign( a );
2184: switch (status->float_rounding_mode) {
2185: case float_round_nearest_even:
2186: if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 )
2187: ) {
2188: return
2189: packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
2190: }
2191: break;
2192: case float_round_ties_away:
2193: if (aExp == 0x3FFE) {
2194: return packFloatx80(aSign, 0x3FFF, LIT64(0x8000000000000000));
2195: }
2196: break;
2197: case float_round_down:
2198: return
2199: aSign ?
2200: packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
2201: : packFloatx80( 0, 0, 0 );
2202: case float_round_up:
2203: return
2204: aSign ? packFloatx80( 1, 0, 0 )
2205: : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
2206: }
2207: return packFloatx80( aSign, 0, 0 );
2208: }
2209: lastBitMask = 1;
2210: lastBitMask <<= 0x403E - aExp;
2211: roundBitsMask = lastBitMask - 1;
2212: z = a;
2213: switch (status->float_rounding_mode) {
2214: case float_round_nearest_even:
2215: z.low += lastBitMask>>1;
2216: if ((z.low & roundBitsMask) == 0) {
2217: z.low &= ~lastBitMask;
2218: }
2219: break;
2220: case float_round_ties_away:
2221: z.low += lastBitMask >> 1;
2222: break;
2223: case float_round_to_zero:
2224: break;
2225: case float_round_up:
2226: if (!extractFloatx80Sign(z)) {
2227: z.low += roundBitsMask;
2228: }
2229: break;
2230: case float_round_down:
2231: if (extractFloatx80Sign(z)) {
2232: z.low += roundBitsMask;
2233: }
2234: break;
2235: default:
2236: abort();
2237: }
2238: z.low &= ~ roundBitsMask;
2239: if ( z.low == 0 ) {
2240: ++z.high;
2241: z.low = LIT64( 0x8000000000000000 );
2242: }
2243: if (z.low != a.low) {
2244: status->float_exception_flags |= float_flag_inexact;
2245: }
2246: return z;
2247:
2248: }
2249:
2250: #ifdef SOFTFLOAT_68K // 09-01-2017: Added for Previous
2251: floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_status *status)
2252: {
2253: flag aSign;
2254: int32_t aExp;
2255: uint64_t lastBitMask, roundBitsMask;
2256: floatx80 z;
2257:
2258: aExp = extractFloatx80Exp( a );
2259: if ( 0x403E <= aExp ) {
2260: if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
2261: return propagateFloatx80NaNOneArg( a, status );
2262: }
2263: return a;
2264: }
2265: if ( aExp < 0x3FFF ) {
2266: if ( ( aExp == 0 )
2267: #ifdef SOFTFLOAT_68K
2268: && ( (uint64_t) extractFloatx80Frac( a ) == 0 ) ) {
2269: #else
2270: && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
2271: #endif
2272: return a;
2273: }
2274: status->float_exception_flags |= float_flag_inexact;
2275: aSign = extractFloatx80Sign( a );
2276: return packFloatx80( aSign, 0, 0 );
2277: }
2278: lastBitMask = 1;
2279: lastBitMask <<= 0x403E - aExp;
2280: roundBitsMask = lastBitMask - 1;
2281: z = a;
2282: z.low &= ~ roundBitsMask;
2283: if ( z.low == 0 ) {
2284: ++z.high;
2285: z.low = LIT64( 0x8000000000000000 );
2286: }
2287: if ( z.low != a.low ) status->float_exception_flags |= float_flag_inexact;
2288: return z;
2289:
2290: }
2291: #endif // End of addition for Previous
2292:
2293: /*----------------------------------------------------------------------------
2294: | Returns the result of adding the absolute values of the extended double-
2295: | precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
2296: | negated before being returned. `zSign' is ignored if the result is a NaN.
2297: | The addition is performed according to the IEC/IEEE Standard for Binary
2298: | Floating-Point Arithmetic.
2299: *----------------------------------------------------------------------------*/
2300:
2301: static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
2302: float_status *status)
2303: {
2304: int32_t aExp, bExp, zExp;
2305: uint64_t aSig, bSig, zSig0, zSig1;
2306: int32_t expDiff;
2307:
2308: aSig = extractFloatx80Frac( a );
2309: aExp = extractFloatx80Exp( a );
2310: bSig = extractFloatx80Frac( b );
2311: bExp = extractFloatx80Exp( b );
2312: #ifdef SOFTFLOAT_68K
2313: if ( aExp == 0 ) {
2314: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2315: }
2316: if ( bExp == 0 ) {
2317: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2318: }
2319: #endif
2320: expDiff = aExp - bExp;
2321: if ( 0 < expDiff ) {
2322: if ( aExp == 0x7FFF ) {
2323: if ((uint64_t)(aSig << 1)) {
2324: return propagateFloatx80NaN(a, b, status);
2325: }
2326: return a;
2327: }
2328: #ifndef SOFTFLOAT_68K
2329: if ( bExp == 0 ) --expDiff;
2330: #endif
2331: shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2332: zExp = aExp;
2333: }
2334: else if ( expDiff < 0 ) {
2335: if ( bExp == 0x7FFF ) {
2336: if ((uint64_t)(bSig << 1)) {
2337: return propagateFloatx80NaN(a, b, status);
2338: }
2339: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2340: }
2341: #ifndef SOFTFLOAT_68K
2342: if ( aExp == 0 ) ++expDiff;
2343: #endif
2344: shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2345: zExp = bExp;
2346: }
2347: else {
2348: if ( aExp == 0x7FFF ) {
2349: if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
2350: return propagateFloatx80NaN(a, b, status);
2351: }
2352: return a;
2353: }
2354: zSig1 = 0;
2355: zSig0 = aSig + bSig;
2356: #ifndef SOFTFLOAT_68K
2357: if ( aExp == 0 ) {
2358: normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
2359: goto roundAndPack;
2360: }
2361: #endif
2362: zExp = aExp;
2363: #ifdef SOFTFLOAT_68K
2364: if ( aSig == 0 && bSig == 0 ) return packFloatx80( zSign, 0, 0 );
2365: if ( aSig == 0 || bSig == 0 ) goto roundAndPack;
2366: #endif
2367: goto shiftRight1;
2368: }
2369: zSig0 = aSig + bSig;
2370: if ( (int64_t) zSig0 < 0 ) goto roundAndPack;
2371: shiftRight1:
2372: shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
2373: zSig0 |= LIT64( 0x8000000000000000 );
2374: ++zExp;
2375: roundAndPack:
2376: return roundAndPackFloatx80(status->floatx80_rounding_precision,
2377: zSign, zExp, zSig0, zSig1, status);
2378: }
2379:
2380: /*----------------------------------------------------------------------------
2381: | Returns the result of subtracting the absolute values of the extended
2382: | double-precision floating-point values `a' and `b'. If `zSign' is 1, the
2383: | difference is negated before being returned. `zSign' is ignored if the
2384: | result is a NaN. The subtraction is performed according to the IEC/IEEE
2385: | Standard for Binary Floating-Point Arithmetic.
2386: *----------------------------------------------------------------------------*/
2387:
2388: static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
2389: float_status *status)
2390: {
2391: int32_t aExp, bExp, zExp;
2392: uint64_t aSig, bSig, zSig0, zSig1;
2393: int32_t expDiff;
2394:
2395: aSig = extractFloatx80Frac( a );
2396: aExp = extractFloatx80Exp( a );
2397: bSig = extractFloatx80Frac( b );
2398: bExp = extractFloatx80Exp( b );
2399: expDiff = aExp - bExp;
2400: if ( 0 < expDiff ) goto aExpBigger;
2401: if ( expDiff < 0 ) goto bExpBigger;
2402: if ( aExp == 0x7FFF ) {
2403: if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
2404: return propagateFloatx80NaN(a, b, status);
2405: }
2406: float_raise(float_flag_invalid, status);
2407: return floatx80_default_nan(status);
2408: }
2409: #ifndef SOFTFLOAT_68K
2410: if ( aExp == 0 ) {
2411: aExp = 1;
2412: bExp = 1;
2413: }
2414: #endif
2415: zSig1 = 0;
2416: if ( bSig < aSig ) goto aBigger;
2417: if ( aSig < bSig ) goto bBigger;
2418: return packFloatx80(status->float_rounding_mode == float_round_down, 0, 0);
2419: bExpBigger:
2420: if ( bExp == 0x7FFF ) {
2421: if ((uint64_t)(bSig << 1)) {
2422: return propagateFloatx80NaN(a, b, status);
2423: }
2424: return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
2425: }
2426: #ifndef SOFTFLOAT_68K
2427: if ( aExp == 0 ) ++expDiff;
2428: #endif
2429: shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2430: bBigger:
2431: sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
2432: zExp = bExp;
2433: zSign ^= 1;
2434: goto normalizeRoundAndPack;
2435: aExpBigger:
2436: if ( aExp == 0x7FFF ) {
2437: if ((uint64_t)(aSig << 1)) {
2438: return propagateFloatx80NaN(a, b, status);
2439: }
2440: return a;
2441: }
2442: #ifndef SOFTFLOAT_68K
2443: if ( bExp == 0 ) --expDiff;
2444: #endif
2445: shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2446: aBigger:
2447: sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
2448: zExp = aExp;
2449: normalizeRoundAndPack:
2450: return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precision,
2451: zSign, zExp, zSig0, zSig1, status);
2452: }
2453:
2454: /*----------------------------------------------------------------------------
2455: | Returns the result of adding the extended double-precision floating-point
2456: | values `a' and `b'. The operation is performed according to the IEC/IEEE
2457: | Standard for Binary Floating-Point Arithmetic.
2458: *----------------------------------------------------------------------------*/
2459:
2460: floatx80 floatx80_add(floatx80 a, floatx80 b, float_status *status)
2461: {
2462: flag aSign, bSign;
2463:
2464: if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
2465: float_raise(float_flag_invalid, status);
2466: return floatx80_default_nan(status);
2467: }
2468: aSign = extractFloatx80Sign( a );
2469: bSign = extractFloatx80Sign( b );
2470: if ( aSign == bSign ) {
2471: return addFloatx80Sigs(a, b, aSign, status);
2472: }
2473: else {
2474: return subFloatx80Sigs(a, b, aSign, status);
2475: }
2476:
2477: }
2478:
2479: /*----------------------------------------------------------------------------
2480: | Returns the result of subtracting the extended double-precision floating-
2481: | point values `a' and `b'. The operation is performed according to the
2482: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2483: *----------------------------------------------------------------------------*/
2484:
2485: floatx80 floatx80_sub(floatx80 a, floatx80 b, float_status *status)
2486: {
2487: flag aSign, bSign;
2488:
2489: if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
2490: float_raise(float_flag_invalid, status);
2491: return floatx80_default_nan(status);
2492: }
2493: aSign = extractFloatx80Sign( a );
2494: bSign = extractFloatx80Sign( b );
2495: if ( aSign == bSign ) {
2496: return subFloatx80Sigs(a, b, aSign, status);
2497: }
2498: else {
2499: return addFloatx80Sigs(a, b, aSign, status);
2500: }
2501:
2502: }
2503:
2504: /*----------------------------------------------------------------------------
2505: | Returns the result of multiplying the extended double-precision floating-
2506: | point values `a' and `b'. The operation is performed according to the
2507: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2508: *----------------------------------------------------------------------------*/
2509:
2510: floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
2511: {
2512: flag aSign, bSign, zSign;
2513: int32_t aExp, bExp, zExp;
2514: uint64_t aSig, bSig, zSig0, zSig1;
2515:
2516: if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
2517: float_raise(float_flag_invalid, status);
2518: return floatx80_default_nan(status);
2519: }
2520: aSig = extractFloatx80Frac( a );
2521: aExp = extractFloatx80Exp( a );
2522: aSign = extractFloatx80Sign( a );
2523: bSig = extractFloatx80Frac( b );
2524: bExp = extractFloatx80Exp( b );
2525: bSign = extractFloatx80Sign( b );
2526: zSign = aSign ^ bSign;
2527: if ( aExp == 0x7FFF ) {
2528: if ( (uint64_t) ( aSig<<1 )
2529: || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
2530: return propagateFloatx80NaN(a, b, status);
2531: }
2532: if ( ( bExp | bSig ) == 0 ) goto invalid;
2533: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2534: }
2535: if ( bExp == 0x7FFF ) {
2536: if ((uint64_t)(bSig << 1)) {
2537: return propagateFloatx80NaN(a, b, status);
2538: }
2539: if ( ( aExp | aSig ) == 0 ) {
2540: invalid:
2541: float_raise(float_flag_invalid, status);
2542: return floatx80_default_nan(status);
2543: }
2544: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2545: }
2546: if ( aExp == 0 ) {
2547: if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2548: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2549: }
2550: if ( bExp == 0 ) {
2551: if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
2552: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2553: }
2554: zExp = aExp + bExp - 0x3FFE;
2555: mul64To128( aSig, bSig, &zSig0, &zSig1 );
2556: if ( 0 < (int64_t) zSig0 ) {
2557: shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
2558: --zExp;
2559: }
2560: return roundAndPackFloatx80(status->floatx80_rounding_precision,
2561: zSign, zExp, zSig0, zSig1, status);
2562: }
2563:
2564: #ifdef SOFTFLOAT_68K // 21-01-2017: Added for Previous
2565: floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_status *status )
2566: {
2567: flag aSign, bSign, zSign;
2568: int32_t aExp, bExp, zExp;
2569: uint64_t aSig, bSig, zSig0, zSig1;
2570: floatx80 z;
2571:
2572: aSig = extractFloatx80Frac( a );
2573: aExp = extractFloatx80Exp( a );
2574: aSign = extractFloatx80Sign( a );
2575: bSig = extractFloatx80Frac( b );
2576: bExp = extractFloatx80Exp( b );
2577: bSign = extractFloatx80Sign( b );
2578: zSign = aSign ^ bSign;
2579: if ( aExp == 0x7FFF ) {
2580: if ( (uint64_t) ( aSig<<1 )
2581: || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
2582: return propagateFloatx80NaN( a, b, status );
2583: }
2584: if ( ( bExp | bSig ) == 0 ) goto invalid;
2585: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2586: }
2587: if ( bExp == 0x7FFF ) {
2588: if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
2589: if ( ( aExp | aSig ) == 0 ) {
2590: invalid:
2591: float_raise( float_flag_invalid, status );
2592: z.low = floatx80_default_nan_low;
2593: z.high = floatx80_default_nan_high;
2594: return z;
2595: }
2596: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2597: }
2598: if ( aExp == 0 ) {
2599: if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2600: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2601: }
2602: if ( bExp == 0 ) {
2603: if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
2604: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2605: }
2606: aSig &= LIT64( 0xFFFFFF0000000000 );
2607: bSig &= LIT64( 0xFFFFFF0000000000 );
2608: zExp = aExp + bExp - 0x3FFE;
2609: mul64To128( aSig, bSig, &zSig0, &zSig1 );
2610: if ( 0 < (int64_t) zSig0 ) {
2611: shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
2612: --zExp;
2613: }
2614: return roundSigAndPackFloatx80( 32, zSign, zExp, zSig0, zSig1, status);
2615:
2616: }
2617: #endif // End of addition for Previous
2618:
2619:
2620: /*----------------------------------------------------------------------------
2621: | Returns the result of dividing the extended double-precision floating-point
2622: | value `a' by the corresponding value `b'. The operation is performed
2623: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2624: *----------------------------------------------------------------------------*/
2625:
2626: floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
2627: {
2628: flag aSign, bSign, zSign;
2629: int32_t aExp, bExp, zExp;
2630: uint64_t aSig, bSig, zSig0, zSig1;
2631: uint64_t rem0, rem1, rem2, term0, term1, term2;
2632:
2633: if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
2634: float_raise(float_flag_invalid, status);
2635: return floatx80_default_nan(status);
2636: }
2637: aSig = extractFloatx80Frac( a );
2638: aExp = extractFloatx80Exp( a );
2639: aSign = extractFloatx80Sign( a );
2640: bSig = extractFloatx80Frac( b );
2641: bExp = extractFloatx80Exp( b );
2642: bSign = extractFloatx80Sign( b );
2643: zSign = aSign ^ bSign;
2644: if ( aExp == 0x7FFF ) {
2645: if ((uint64_t)(aSig << 1)) {
2646: return propagateFloatx80NaN(a, b, status);
2647: }
2648: if ( bExp == 0x7FFF ) {
2649: if ((uint64_t)(bSig << 1)) {
2650: return propagateFloatx80NaN(a, b, status);
2651: }
2652: goto invalid;
2653: }
2654: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2655: }
2656: if ( bExp == 0x7FFF ) {
2657: if ((uint64_t)(bSig << 1)) {
2658: return propagateFloatx80NaN(a, b, status);
2659: }
2660: return packFloatx80( zSign, 0, 0 );
2661: }
2662: if ( bExp == 0 ) {
2663: if ( bSig == 0 ) {
2664: if ( ( aExp | aSig ) == 0 ) {
2665: invalid:
2666: float_raise(float_flag_invalid, status);
2667: return floatx80_default_nan(status);
2668: }
2669: float_raise(float_flag_divbyzero, status);
2670: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2671: }
2672: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2673: }
2674: if ( aExp == 0 ) {
2675: if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2676: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2677: }
2678: zExp = aExp - bExp + 0x3FFE;
2679: rem1 = 0;
2680: if ( bSig <= aSig ) {
2681: shift128Right( aSig, 0, 1, &aSig, &rem1 );
2682: ++zExp;
2683: }
2684: zSig0 = estimateDiv128To64( aSig, rem1, bSig );
2685: mul64To128( bSig, zSig0, &term0, &term1 );
2686: sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
2687: while ( (int64_t) rem0 < 0 ) {
2688: --zSig0;
2689: add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
2690: }
2691: zSig1 = estimateDiv128To64( rem1, 0, bSig );
2692: if ( (uint64_t) ( zSig1<<1 ) <= 8 ) {
2693: mul64To128( bSig, zSig1, &term1, &term2 );
2694: sub128( rem1, 0, term1, term2, &rem1, &rem2 );
2695: while ( (int64_t) rem1 < 0 ) {
2696: --zSig1;
2697: add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
2698: }
2699: zSig1 |= ( ( rem1 | rem2 ) != 0 );
2700: }
2701: return roundAndPackFloatx80(status->floatx80_rounding_precision,
2702: zSign, zExp, zSig0, zSig1, status);
2703: }
2704:
2705: #ifdef SOFTFLOAT_68K // 21-01-2017: Addition for Previous
2706: floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status )
2707: {
2708: flag aSign, bSign, zSign;
2709: int32_t aExp, bExp, zExp;
2710: uint64_t aSig, bSig, zSig0, zSig1;
2711: uint64_t rem0, rem1, rem2, term0, term1, term2;
2712: floatx80 z;
2713:
2714: aSig = extractFloatx80Frac( a );
2715: aExp = extractFloatx80Exp( a );
2716: aSign = extractFloatx80Sign( a );
2717: bSig = extractFloatx80Frac( b );
2718: bExp = extractFloatx80Exp( b );
2719: bSign = extractFloatx80Sign( b );
2720: zSign = aSign ^ bSign;
2721: if ( aExp == 0x7FFF ) {
2722: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
2723: if ( bExp == 0x7FFF ) {
2724: if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
2725: goto invalid;
2726: }
2727: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2728: }
2729: if ( bExp == 0x7FFF ) {
2730: if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
2731: return packFloatx80( zSign, 0, 0 );
2732: }
2733: if ( bExp == 0 ) {
2734: if ( bSig == 0 ) {
2735: if ( ( aExp | aSig ) == 0 ) {
2736: invalid:
2737: float_raise( float_flag_invalid, status );
2738: z.low = floatx80_default_nan_low;
2739: z.high = floatx80_default_nan_high;
2740: return z;
2741: }
2742: float_raise( float_flag_divbyzero, status );
2743: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low );
2744: }
2745: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2746: }
2747: if ( aExp == 0 ) {
2748: if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2749: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2750: }
2751:
2752: zExp = aExp - bExp + 0x3FFE;
2753: rem1 = 0;
2754: if ( bSig <= aSig ) {
2755: shift128Right( aSig, 0, 1, &aSig, &rem1 );
2756: ++zExp;
2757: }
2758: zSig0 = estimateDiv128To64( aSig, rem1, bSig );
2759: mul64To128( bSig, zSig0, &term0, &term1 );
2760: sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
2761: while ( (int64_t) rem0 < 0 ) {
2762: --zSig0;
2763: add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
2764: }
2765: zSig1 = estimateDiv128To64( rem1, 0, bSig );
2766: if ( (uint64_t) ( zSig1<<1 ) <= 8 ) {
2767: mul64To128( bSig, zSig1, &term1, &term2 );
2768: sub128( rem1, 0, term1, term2, &rem1, &rem2 );
2769: while ( (int64_t) rem1 < 0 ) {
2770: --zSig1;
2771: add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
2772: }
2773: zSig1 |= ( ( rem1 | rem2 ) != 0 );
2774: }
2775: return roundSigAndPackFloatx80( 32, zSign, zExp, zSig0, zSig1, status);
2776:
2777: }
2778: #endif // End of addition for Previous
2779:
2780:
2781: /*----------------------------------------------------------------------------
2782: | Returns the remainder of the extended double-precision floating-point value
2783: | `a' with respect to the corresponding value `b'. The operation is performed
2784: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2785: *----------------------------------------------------------------------------*/
2786:
2787: #ifndef SOFTFLOAT_68K
2788: floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
2789: {
2790: flag aSign, zSign;
2791: int32_t aExp, bExp, expDiff;
2792: uint64_t aSig0, aSig1, bSig;
2793: uint64_t q, term0, term1, alternateASig0, alternateASig1;
2794:
2795: if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
2796: float_raise(float_flag_invalid, status);
2797: return floatx80_default_nan(status);
2798: }
2799: aSig0 = extractFloatx80Frac( a );
2800: aExp = extractFloatx80Exp( a );
2801: aSign = extractFloatx80Sign( a );
2802: bSig = extractFloatx80Frac( b );
2803: bExp = extractFloatx80Exp( b );
2804: if ( aExp == 0x7FFF ) {
2805: if ( (uint64_t) ( aSig0<<1 )
2806: || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
2807: return propagateFloatx80NaN(a, b, status);
2808: }
2809: goto invalid;
2810: }
2811: if ( bExp == 0x7FFF ) {
2812: if ((uint64_t)(bSig << 1)) {
2813: return propagateFloatx80NaN(a, b, status);
2814: }
2815: return a;
2816: }
2817: if ( bExp == 0 ) {
2818: if ( bSig == 0 ) {
2819: invalid:
2820: float_raise(float_flag_invalid, status);
2821: return floatx80_default_nan(status);
2822: }
2823: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2824: }
2825: if ( aExp == 0 ) {
2826: if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
2827: normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
2828: }
2829: bSig |= LIT64( 0x8000000000000000 );
2830: zSign = aSign;
2831: expDiff = aExp - bExp;
2832: aSig1 = 0;
2833: if ( expDiff < 0 ) {
2834: if ( expDiff < -1 ) return a;
2835: shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
2836: expDiff = 0;
2837: }
2838: q = ( bSig <= aSig0 );
2839: if ( q ) aSig0 -= bSig;
2840: expDiff -= 64;
2841: while ( 0 < expDiff ) {
2842: q = estimateDiv128To64( aSig0, aSig1, bSig );
2843: q = ( 2 < q ) ? q - 2 : 0;
2844: mul64To128( bSig, q, &term0, &term1 );
2845: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2846: shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
2847: expDiff -= 62;
2848: }
2849: expDiff += 64;
2850: if ( 0 < expDiff ) {
2851: q = estimateDiv128To64( aSig0, aSig1, bSig );
2852: q = ( 2 < q ) ? q - 2 : 0;
2853: q >>= 64 - expDiff;
2854: mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
2855: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2856: shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
2857: while ( le128( term0, term1, aSig0, aSig1 ) ) {
2858: ++q;
2859: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2860: }
2861: }
2862: else {
2863: term1 = 0;
2864: term0 = bSig;
2865: }
2866: sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
2867: if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
2868: || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
2869: && ( q & 1 ) )
2870: ) {
2871: aSig0 = alternateASig0;
2872: aSig1 = alternateASig1;
2873: zSign = ! zSign;
2874: }
2875: return
2876: normalizeRoundAndPackFloatx80(
2877: 80, zSign, bExp + expDiff, aSig0, aSig1, status);
2878:
2879: }
2880: #else // 09-01-2017: Modified version for Previous
2881: floatx80 floatx80_rem( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_status *status )
2882: {
2883: flag aSign, bSign, zSign;
2884: int32_t aExp, bExp, expDiff;
2885: uint64_t aSig0, aSig1, bSig;
2886: uint64_t qTemp, term0, term1, alternateASig0, alternateASig1;
2887: floatx80 z;
2888:
2889: aSig0 = extractFloatx80Frac( a );
2890: aExp = extractFloatx80Exp( a );
2891: aSign = extractFloatx80Sign( a );
2892: bSig = extractFloatx80Frac( b );
2893: bExp = extractFloatx80Exp( b );
2894: bSign = extractFloatx80Sign( b );
2895:
2896: if ( aExp == 0x7FFF ) {
2897: if ( (uint64_t) ( aSig0<<1 )
2898: || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
2899: return propagateFloatx80NaN( a, b, status );
2900: }
2901: goto invalid;
2902: }
2903: if ( bExp == 0x7FFF ) {
2904: if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
2905: *s = (aSign != bSign);
2906: *q = 0;
2907: return a;
2908: }
2909: if ( bExp == 0 ) {
2910: if ( bSig == 0 ) {
2911: invalid:
2912: float_raise( float_flag_invalid, status );
2913: z.low = floatx80_default_nan_low;
2914: z.high = floatx80_default_nan_high;
2915: return z;
2916: }
2917: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2918: }
2919: if ( aExp == 0 ) {
2920: #ifdef SOFTFLOAT_68K
2921: if ( aSig0 == 0 ) {
2922: *s = (aSign != bSign);
2923: *q = 0;
2924: return a;
2925: }
2926: #else
2927: if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
2928: #endif
2929: normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
2930: }
2931: bSig |= LIT64( 0x8000000000000000 );
2932: zSign = aSign;
2933: expDiff = aExp - bExp;
2934: *s = (aSign != bSign);
2935: aSig1 = 0;
2936: if ( expDiff < 0 ) {
2937: if ( expDiff < -1 ) return a;
2938: shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
2939: expDiff = 0;
2940: }
2941: qTemp = ( bSig <= aSig0 );
2942: if ( qTemp ) aSig0 -= bSig;
2943: *q = ( expDiff > 63 ) ? 0 : ( qTemp<<expDiff );
2944: expDiff -= 64;
2945: while ( 0 < expDiff ) {
2946: qTemp = estimateDiv128To64( aSig0, aSig1, bSig );
2947: qTemp = ( 2 < qTemp ) ? qTemp - 2 : 0;
2948: mul64To128( bSig, qTemp, &term0, &term1 );
2949: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2950: shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
2951: *q = ( expDiff > 63 ) ? 0 : ( qTemp<<expDiff );
2952: expDiff -= 62;
2953: }
2954: expDiff += 64;
2955: if ( 0 < expDiff ) {
2956: qTemp = estimateDiv128To64( aSig0, aSig1, bSig );
2957: qTemp = ( 2 < qTemp ) ? qTemp - 2 : 0;
2958: qTemp >>= 64 - expDiff;
2959: mul64To128( bSig, qTemp<<( 64 - expDiff ), &term0, &term1 );
2960: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2961: shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
2962: while ( le128( term0, term1, aSig0, aSig1 ) ) {
2963: ++qTemp;
2964: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
2965: }
2966: *q += qTemp;
2967: }
2968: else {
2969: term1 = 0;
2970: term0 = bSig;
2971: }
2972: sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
2973: if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
2974: || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
2975: && ( qTemp & 1 ) )
2976: ) {
2977: aSig0 = alternateASig0;
2978: aSig1 = alternateASig1;
2979: zSign = ! zSign;
2980: ++*q;
2981: }
2982: return
2983: normalizeRoundAndPackFloatx80(
2984: 80, zSign, bExp + expDiff, aSig0, aSig1, status );
2985:
2986: }
2987: #endif // End of modification
2988:
2989:
2990: #ifdef SOFTFLOAT_68K // 08-01-2017: Added for Previous
2991: /*----------------------------------------------------------------------------
2992: | Returns the modulo remainder of the extended double-precision floating-point
2993: | value `a' with respect to the corresponding value `b'.
2994: *----------------------------------------------------------------------------*/
2995:
2996: floatx80 floatx80_mod( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_status *status )
2997: {
2998: flag aSign, bSign, zSign;
2999: int32_t aExp, bExp, expDiff;
3000: uint64_t aSig0, aSig1, bSig;
3001: uint64_t qTemp, term0, term1;
3002: floatx80 z;
3003:
3004: aSig0 = extractFloatx80Frac( a );
3005: aExp = extractFloatx80Exp( a );
3006: aSign = extractFloatx80Sign( a );
3007: bSig = extractFloatx80Frac( b );
3008: bExp = extractFloatx80Exp( b );
3009: bSign = extractFloatx80Sign( b );
3010:
3011: if ( aExp == 0x7FFF ) {
3012: if ( (uint64_t) ( aSig0<<1 )
3013: || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
3014: return propagateFloatx80NaN( a, b, status );
3015: }
3016: goto invalid;
3017: }
3018: if ( bExp == 0x7FFF ) {
3019: if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
3020: *s = (aSign != bSign);
3021: *q = 0;
3022: return a;
3023: }
3024: if ( bExp == 0 ) {
3025: if ( bSig == 0 ) {
3026: invalid:
3027: float_raise( float_flag_invalid, status );
3028: z.low = floatx80_default_nan_low;
3029: z.high = floatx80_default_nan_high;
3030: return z;
3031: }
3032: normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
3033: }
3034: if ( aExp == 0 ) {
3035: #ifdef SOFTFLOAT_68K
3036: if ( aSig0 == 0 ) {
3037: *s = (aSign != bSign);
3038: *q = 0;
3039: return a;
3040: }
3041: #else
3042: if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
3043: #endif
3044: normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3045: }
3046: bSig |= LIT64( 0x8000000000000000 );
3047: zSign = aSign;
3048: expDiff = aExp - bExp;
3049: *s = (aSign != bSign);
3050: aSig1 = 0;
3051: if ( expDiff < 0 ) return a;
3052: qTemp = ( bSig <= aSig0 );
3053: if ( qTemp ) aSig0 -= bSig;
3054: *q = ( expDiff > 63 ) ? 0 : ( qTemp<<expDiff );
3055: expDiff -= 64;
3056: while ( 0 < expDiff ) {
3057: qTemp = estimateDiv128To64( aSig0, aSig1, bSig );
3058: qTemp = ( 2 < qTemp ) ? qTemp - 2 : 0;
3059: mul64To128( bSig, qTemp, &term0, &term1 );
3060: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3061: shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
3062: *q = ( expDiff > 63 ) ? 0 : ( qTemp<<expDiff );
3063: expDiff -= 62;
3064: }
3065: expDiff += 64;
3066: if ( 0 < expDiff ) {
3067: qTemp = estimateDiv128To64( aSig0, aSig1, bSig );
3068: qTemp = ( 2 < qTemp ) ? qTemp - 2 : 0;
3069: qTemp >>= 64 - expDiff;
3070: mul64To128( bSig, qTemp<<( 64 - expDiff ), &term0, &term1 );
3071: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3072: shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
3073: while ( le128( term0, term1, aSig0, aSig1 ) ) {
3074: ++qTemp;
3075: sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3076: }
3077: *q += qTemp;
3078: }
3079: return
3080: normalizeRoundAndPackFloatx80(
3081: 80, zSign, bExp + expDiff, aSig0, aSig1, status );
3082:
3083: }
3084: #endif // end of addition for Previous
3085:
3086:
3087: /*----------------------------------------------------------------------------
3088: | Returns the square root of the extended double-precision floating-point
3089: | value `a'. The operation is performed according to the IEC/IEEE Standard
3090: | for Binary Floating-Point Arithmetic.
3091: *----------------------------------------------------------------------------*/
3092:
3093: floatx80 floatx80_sqrt(floatx80 a, float_status *status)
3094: {
3095: flag aSign;
3096: int32_t aExp, zExp;
3097: uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
3098: uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
3099:
3100: if (floatx80_invalid_encoding(a)) {
3101: float_raise(float_flag_invalid, status);
3102: return floatx80_default_nan(status);
3103: }
3104: aSig0 = extractFloatx80Frac( a );
3105: aExp = extractFloatx80Exp( a );
3106: aSign = extractFloatx80Sign( a );
3107: if ( aExp == 0x7FFF ) {
3108: if ((uint64_t)(aSig0 << 1)) {
3109: return propagateFloatx80NaNOneArg(a, status);
3110: }
3111: if ( ! aSign ) return a;
3112: goto invalid;
3113: }
3114: if ( aSign ) {
3115: if ( ( aExp | aSig0 ) == 0 ) return a;
3116: invalid:
3117: float_raise(float_flag_invalid, status);
3118: return floatx80_default_nan(status);
3119: }
3120: if ( aExp == 0 ) {
3121: if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
3122: normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3123: }
3124: zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
3125: zSig0 = estimateSqrt32( aExp, aSig0>>32 );
3126: shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
3127: zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
3128: doubleZSig0 = zSig0<<1;
3129: mul64To128( zSig0, zSig0, &term0, &term1 );
3130: sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
3131: while ( (int64_t) rem0 < 0 ) {
3132: --zSig0;
3133: doubleZSig0 -= 2;
3134: add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
3135: }
3136: zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
3137: if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
3138: if ( zSig1 == 0 ) zSig1 = 1;
3139: mul64To128( doubleZSig0, zSig1, &term1, &term2 );
3140: sub128( rem1, 0, term1, term2, &rem1, &rem2 );
3141: mul64To128( zSig1, zSig1, &term2, &term3 );
3142: sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
3143: while ( (int64_t) rem1 < 0 ) {
3144: --zSig1;
3145: shortShift128Left( 0, zSig1, 1, &term2, &term3 );
3146: term3 |= 1;
3147: term2 |= doubleZSig0;
3148: add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
3149: }
3150: zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
3151: }
3152: shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
3153: zSig0 |= doubleZSig0;
3154: return roundAndPackFloatx80(status->floatx80_rounding_precision,
3155: 0, zExp, zSig0, zSig1, status);
3156: }
3157:
3158:
3159: #ifdef SOFTFLOAT_68K // 07-01-2017: Added for Previous
3160: /*----------------------------------------------------------------------------
3161: | Returns the mantissa of the extended double-precision floating-point
3162: | value `a'.
3163: *----------------------------------------------------------------------------*/
3164:
3165: floatx80 floatx80_getman( floatx80 a, float_status *status)
3166: {
3167: flag aSign;
3168: int32_t aExp;
3169: uint64_t aSig;
3170:
3171: aSig = extractFloatx80Frac( a );
3172: aExp = extractFloatx80Exp( a );
3173: aSign = extractFloatx80Sign( a );
3174:
3175: if ( aExp == 0x7FFF ) {
3176: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status );
3177: float_raise( float_flag_invalid, status );
3178: a.low = floatx80_default_nan_low;
3179: a.high = floatx80_default_nan_high;
3180: return a;
3181: }
3182:
3183: if ( aExp == 0 ) {
3184: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
3185: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3186: }
3187:
3188: return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign, 0x3FFF, aSig, 0, status);
3189: }
3190:
3191: /*----------------------------------------------------------------------------
3192: | Returns the exponent of the extended double-precision floating-point
3193: | value `a' as an extended double-precision value.
3194: *----------------------------------------------------------------------------*/
3195:
3196: floatx80 floatx80_getexp( floatx80 a, float_status *status)
3197: {
3198: flag aSign;
3199: int32_t aExp;
3200: uint64_t aSig;
3201:
3202: aSig = extractFloatx80Frac( a );
3203: aExp = extractFloatx80Exp( a );
3204: aSign = extractFloatx80Sign( a );
3205:
3206: if ( aExp == 0x7FFF ) {
3207: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status );
3208: float_raise( float_flag_invalid, status );
3209: a.low = floatx80_default_nan_low;
3210: a.high = floatx80_default_nan_high;
3211: return a;
3212: }
3213:
3214: if ( aExp == 0 ) {
3215: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
3216: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3217: }
3218:
3219: return int32_to_floatx80(aExp - 0x3FFF);
3220: }
3221:
3222: /*----------------------------------------------------------------------------
3223: | Scales extended double-precision floating-point value in operand `a' by
3224: | value `b'. The function truncates the value in the second operand 'b' to
3225: | an integral value and adds that value to the exponent of the operand 'a'.
3226: | The operation performed according to the IEC/IEEE Standard for Binary
3227: | Floating-Point Arithmetic.
3228: *----------------------------------------------------------------------------*/
3229:
3230: floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
3231: {
3232: flag aSign, bSign;
3233: int32_t aExp, bExp, shiftCount;
3234: uint64_t aSig, bSig;
3235:
3236: aSig = extractFloatx80Frac(a);
3237: aExp = extractFloatx80Exp(a);
3238: aSign = extractFloatx80Sign(a);
3239: bSig = extractFloatx80Frac(b);
3240: bExp = extractFloatx80Exp(b);
3241: bSign = extractFloatx80Sign(b);
3242:
3243: if ( bExp == 0x7FFF ) {
3244: if ( (uint64_t) ( bSig<<1 ) ||
3245: ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) ) {
3246: return propagateFloatx80NaN( a, b, status );
3247: }
3248: float_raise( float_flag_invalid, status );
3249: a.low = floatx80_default_nan_low;
3250: a.high = floatx80_default_nan_high;
3251: return a;
3252: }
3253: if ( aExp == 0x7FFF ) {
3254: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, status );
3255: return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3256: }
3257: if ( aExp == 0 ) {
3258: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0);
3259: if ( bExp < 0x3FFF ) return a;
3260: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3261: }
3262:
3263: if ( bExp < 0x3FFF ) return a;
3264:
3265: if ( 0x400F < bExp ) {
3266: aExp = bSign ? -0x6001 : 0xE000;
3267: return roundAndPackFloatx80(
3268: status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
3269: }
3270:
3271: shiftCount = 0x403E - bExp;
3272: bSig >>= shiftCount;
3273: aExp = bSign ? ( aExp - bSig ) : ( aExp + bSig );
3274:
3275: return roundAndPackFloatx80(
3276: status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status);
3277:
3278: }
3279:
3280: /*-----------------------------------------------------------------------------
3281: | Calculates the absolute value of the extended double-precision floating-point
3282: | value `a'. The operation is performed according to the IEC/IEEE Standard
3283: | for Binary Floating-Point Arithmetic.
3284: *----------------------------------------------------------------------------*/
3285:
3286: floatx80 floatx80_abs(floatx80 a, float_status *status)
3287: {
3288: int32_t aExp;
3289: uint64_t aSig;
3290:
3291: aSig = extractFloatx80Frac(a);
3292: aExp = extractFloatx80Exp(a);
3293:
3294: if ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) {
3295: return propagateFloatx80NaNOneArg( a, status );
3296: }
3297:
3298: if ( aExp == 0 ) {
3299: if ( aSig == 0 ) return packFloatx80( 0, 0, 0 );
3300: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3301: }
3302:
3303: return roundAndPackFloatx80(
3304: status->floatx80_rounding_precision, 0, aExp, aSig, 0, status );
3305:
3306: }
3307:
3308: /*-----------------------------------------------------------------------------
3309: | Changes the sign of the extended double-precision floating-point value 'a'.
3310: | The operation is performed according to the IEC/IEEE Standard for Binary
3311: | Floating-Point Arithmetic.
3312: *----------------------------------------------------------------------------*/
3313:
3314: floatx80 floatx80_neg(floatx80 a, float_status *status)
3315: {
3316: flag aSign;
3317: int32_t aExp;
3318: uint64_t aSig;
3319:
3320: aSig = extractFloatx80Frac(a);
3321: aExp = extractFloatx80Exp(a);
3322: aSign = extractFloatx80Sign(a);
3323:
3324: if ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) {
3325: return propagateFloatx80NaNOneArg( a, status );
3326: }
3327:
3328: aSign = !aSign;
3329:
3330: if ( aExp == 0 ) {
3331: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
3332: normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3333: }
3334:
3335: return roundAndPackFloatx80(
3336: status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
3337:
3338: }
3339:
3340: /*----------------------------------------------------------------------------
3341: | Returns the result of comparing the extended double-precision floating-
3342: | point values `a' and `b'. The result is abstracted for matching the
3343: | corresponding condition codes.
3344: *----------------------------------------------------------------------------*/
3345:
3346: floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status )
3347: {
3348: flag aSign, bSign;
3349: int32_t aExp, bExp;
3350: uint64_t aSig, bSig;
3351:
3352: aSig = extractFloatx80Frac( a );
3353: aExp = extractFloatx80Exp( a );
3354: aSign = extractFloatx80Sign( a );
3355: bSig = extractFloatx80Frac( b );
3356: bExp = extractFloatx80Exp( b );
3357: bSign = extractFloatx80Sign( b );
3358:
3359: if ( ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) ||
3360: ( bExp == 0x7FFF && (uint64_t) ( bSig<<1 ) ) ) {
3361: return propagateFloatx80NaN( packFloatx80( 0, aExp, aSig ),
3362: packFloatx80( 0, bExp, bSig ), status );
3363: }
3364:
3365: if ( bExp < aExp ) return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
3366: if ( aExp < bExp ) return packFloatx80( bSign ^ 1, 0x3FFF, LIT64( 0x8000000000000000 ) );
3367:
3368: if ( aExp == 0x7FFF ) {
3369: if ( aSign == bSign ) return packFloatx80( aSign, 0, 0 );
3370: return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
3371: }
3372:
3373: if ( bSig < aSig ) return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
3374: if ( aSig < bSig ) return packFloatx80( bSign ^ 1, 0x3FFF, LIT64( 0x8000000000000000 ) );
3375:
3376: if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
3377:
3378: if ( aSign == bSign ) return packFloatx80( 0, 0, 0 );
3379:
3380: return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
3381:
3382: }
3383:
3384: floatx80 floatx80_tst( floatx80 a, float_status *status )
3385: {
3386: int32_t aExp;
3387: uint64_t aSig;
3388:
3389: aSig = extractFloatx80Frac( a );
3390: aExp = extractFloatx80Exp( a );
3391:
3392: if ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) )
3393: return propagateFloatx80NaNOneArg( a, status );
3394: return a;
3395: }
3396:
3397: floatx80 floatx80_move( floatx80 a, float_status *status )
3398: {
3399: flag aSign;
3400: int32_t aExp;
3401: uint64_t aSig;
3402:
3403: aSig = extractFloatx80Frac( a );
3404: aExp = extractFloatx80Exp( a );
3405: aSign = extractFloatx80Sign( a );
3406:
3407: if ( aExp == 0x7FFF ) {
3408: if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status );
3409: return a;
3410: }
3411: if ( aExp == 0 ) {
3412: if ( aSig == 0 ) return a;
3413: normalizeRoundAndPackFloatx80( status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
3414: }
3415: return roundAndPackFloatx80( status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
3416: }
3417:
3418: floatx80 floatx80_denormalize( floatx80 a, flag eSign)
3419: {
3420: flag aSign;
3421: int32_t aExp;
3422: uint64_t aSig;
3423: int32_t shiftCount;
3424:
3425: aSig = extractFloatx80Frac( a );
3426: aExp = extractFloatx80Exp( a );
3427: aSign = extractFloatx80Sign( a );
3428:
3429: if ( eSign ) {
3430: shiftCount = 0x8000 - aExp;
3431: aExp = 0;
3432: if (shiftCount > 63) {
3433: aSig = 0;
3434: } else {
3435: aSig >>= shiftCount;
3436: }
3437: }
3438: return packFloatx80(aSign, aExp, aSig);
3439: }
3440:
3441: #endif // End of addition for Previous
3442:
3443: /*----------------------------------------------------------------------------
3444: | Returns 1 if the extended double-precision floating-point value `a' is
3445: | equal to the corresponding value `b', and 0 otherwise. The comparison is
3446: | performed according to the IEC/IEEE Standard for Binary Floating-Point
3447: | Arithmetic.
3448: *----------------------------------------------------------------------------*/
3449:
3450: flag floatx80_eq( floatx80 a, floatx80 b, float_status *status )
3451: {
3452: if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3453: && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
3454: || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3455: && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
3456: ) {
3457: if ( floatx80_is_signaling_nan( a )
3458: || floatx80_is_signaling_nan( b ) ) {
3459: float_raise( float_flag_invalid, status );
3460: }
3461: return 0;
3462: }
3463: return
3464: ( a.low == b.low )
3465: && ( ( a.high == b.high )
3466: || ( ( a.low == 0 )
3467: && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
3468: );
3469:
3470: }
3471:
3472: /*----------------------------------------------------------------------------
3473: | Returns 1 if the extended double-precision floating-point value `a' is
3474: | less than or equal to the corresponding value `b', and 0 otherwise. The
3475: | comparison is performed according to the IEC/IEEE Standard for Binary
3476: | Floating-Point Arithmetic.
3477: *----------------------------------------------------------------------------*/
3478:
3479: flag floatx80_le( floatx80 a, floatx80 b, float_status *status )
3480: {
3481: flag aSign, bSign;
3482:
3483: if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3484: && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
3485: || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3486: && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
3487: ) {
3488: float_raise( float_flag_invalid, status );
3489: return 0;
3490: }
3491: aSign = extractFloatx80Sign( a );
3492: bSign = extractFloatx80Sign( b );
3493: if ( aSign != bSign ) {
3494: return
3495: aSign
3496: || ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3497: == 0 );
3498: }
3499: return
3500: aSign ? le128( b.high, b.low, a.high, a.low )
3501: : le128( a.high, a.low, b.high, b.low );
3502: }
3503:
3504: /*----------------------------------------------------------------------------
3505: | Returns 1 if the extended double-precision floating-point value `a' is
3506: | less than the corresponding value `b', and 0 otherwise. The comparison
3507: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
3508: | Arithmetic.
3509: *----------------------------------------------------------------------------*/
3510:
3511: flag floatx80_lt( floatx80 a, floatx80 b, float_status *status )
3512: {
3513: flag aSign, bSign;
3514:
3515: if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
3516: && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
3517: || ( ( extractFloatx80Exp( b ) == 0x7FFF )
3518: && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
3519: ) {
3520: float_raise( float_flag_invalid, status );
3521: return 0;
3522: }
3523: aSign = extractFloatx80Sign( a );
3524: bSign = extractFloatx80Sign( b );
3525: if ( aSign != bSign ) {
3526: return
3527: aSign
3528: && ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3529: != 0 );
3530: }
3531: return
3532: aSign ? lt128( b.high, b.low, a.high, a.low )
3533: : lt128( a.high, a.low, b.high, b.low );
3534:
3535: }
3536:
3537:
3538: /*----------------------------------------------------------------------------
3539: | Returns the result of converting the 64-bit two's complement integer `a'
3540: | to the extended double-precision floating-point format. The conversion
3541: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
3542: | Arithmetic.
3543: *----------------------------------------------------------------------------*/
3544:
3545: floatx80 int64_to_floatx80( int64_t a )
3546: {
3547: flag zSign;
3548: uint64_t absA;
3549: int8_t shiftCount;
3550:
3551: if ( a == 0 ) return packFloatx80( 0, 0, 0 );
3552: zSign = ( a < 0 );
3553: absA = zSign ? - a : a;
3554: shiftCount = countLeadingZeros64( absA );
3555: return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
3556: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.