1 /* This file is distributed under the University of Illinois Open Source
2 * License. See LICENSE.TXT for details.
5 /* long double __gcc_qadd(long double x, long double y);
6 * This file implements the PowerPC 128-bit double-double add operation.
7 * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)
12 long double __gcc_qadd(long double x
, long double y
)
14 static const uint32_t infinityHi
= UINT32_C(0x7ff00000);
16 DD dst
= { .ld
= x
}, src
= { .ld
= y
};
18 register double A
= dst
.s
.hi
, a
= dst
.s
.lo
,
19 B
= src
.s
.hi
, b
= src
.s
.lo
;
21 /* If both operands are zero: */
22 if ((A
== 0.0) && (B
== 0.0)) {
28 /* If either operand is NaN or infinity: */
29 const doublebits abits
= { .d
= A
};
30 const doublebits bbits
= { .d
= B
};
31 if ((((uint32_t)(abits
.x
>> 32) & infinityHi
) == infinityHi
) ||
32 (((uint32_t)(bbits
.x
>> 32) & infinityHi
) == infinityHi
)) {
38 /* If the computation overflows: */
39 /* This may be playing things a little bit fast and loose, but it will do for a start. */
40 const double testForOverflow
= A
+ (B
+ (a
+ b
));
41 const doublebits testbits
= { .d
= testForOverflow
};
42 if (((uint32_t)(testbits
.x
>> 32) & infinityHi
) == infinityHi
) {
43 dst
.s
.hi
= testForOverflow
;
53 H
= B
+ (A
- (A
+ B
));
54 T
= b
+ (a
- (a
+ b
));
55 h
= A
+ (B
- (A
+ B
));
56 t
= a
+ (b
- (a
+ b
));
58 if (fabs(A
) <= fabs(B
))
67 if (fabs(a
) <= fabs(b
))
73 dst
.s
.lo
= (W
- Y
) + w
;