38 #include <linux/kernel.h>
40 #include <asm/div64.h>
42 #define LIT64( a ) a##LL
52 typedef unsigned long long int bits64;
62 typedef unsigned long long int uint64;
63 typedef signed long long int int64;
108 static void normalizeFloat64Subnormal(
bits64 aSig,
int16 * zExpPtr,
111 static void normalizeFloat32Subnormal(
bits32 aSig,
int16 * zExpPtr,
116 return a &
LIT64(0x000FFFFFFFFFFFFF);
126 return (a >> 52) & 0x7FF;
131 return (a >> 23) & 0xFF;
141 return a & 0x007FFFFF;
146 return (((
bits64) zSign) << 63) + (((
bits64) zExp) << 52) + zSig;
155 }
else if (count < 64) {
156 z = (a >>
count) | ((a << ((-count) & 63)) != 0);
165 static const int8 countLeadingZerosHigh[] = {
166 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
167 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
168 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
169 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
170 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
171 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
172 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
173 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
194 shiftCount += countLeadingZerosHigh[a >> 24];
204 if (a < ((
bits64) 1) << 32) {
209 shiftCount += countLeadingZeros32(a);
218 shiftCount = countLeadingZeros64(zSig) - 1;
219 return roundAndPackFloat64(zSign, zExp - shiftCount,
226 int16 aExp, bExp, zExp;
234 expDiff = aExp - bExp;
257 aSig |=
LIT64(0x4000000000000000);
260 bSig |=
LIT64(0x4000000000000000);
265 goto normalizeRoundAndPack;
273 bSig |=
LIT64(0x4000000000000000);
276 aSig |=
LIT64(0x4000000000000000);
280 normalizeRoundAndPack:
282 return normalizeRoundAndPackFloat64(zSign, zExp, zSig);
287 int16 aExp, bExp, zExp;
295 expDiff = aExp - bExp;
305 bSig |=
LIT64(0x2000000000000000);
309 }
else if (expDiff < 0) {
316 aSig |=
LIT64(0x2000000000000000);
326 zSig =
LIT64(0x4000000000000000) + aSig + bSig;
330 aSig |=
LIT64(0x2000000000000000);
331 zSig = (aSig + bSig) << 1;
338 return roundAndPackFloat64(zSign, zExp, zSig);
344 return (((
bits32) zSign) << 31) + (((
bits32) zExp) << 23) + zSig;
352 }
else if (count < 32) {
353 z = (a >>
count) | ((a << ((-count) & 31)) != 0);
362 flag roundNearestEven;
363 int8 roundIncrement, roundBits;
368 roundIncrement = 0x40;
369 if (!roundNearestEven) {
372 roundBits = zSig & 0x7F;
373 if (0xFD <= (
bits16) zExp) {
376 && ((
sbits32) (zSig + roundIncrement) < 0))
380 0) - (roundIncrement == 0);
384 || (zSig + roundIncrement < 0x80000000);
387 roundBits = zSig & 0x7F;
388 if (isTiny && roundBits)
394 zSig = (zSig + roundIncrement) >> 7;
395 zSig &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
406 shiftCount = countLeadingZeros32(zSig) - 1;
407 return roundAndPackFloat32(zSign, zExp - shiftCount,
413 flag roundNearestEven;
414 int16 roundIncrement, roundBits;
419 roundIncrement = 0x200;
420 if (!roundNearestEven) {
423 roundBits = zSig & 0x3FF;
424 if (0x7FD <= (
bits16) zExp) {
427 && ((
sbits64) (zSig + roundIncrement) < 0))
431 0) - (roundIncrement == 0);
435 || (zSig + roundIncrement <
436 LIT64(0x8000000000000000));
439 roundBits = zSig & 0x3FF;
440 if (isTiny && roundBits)
446 zSig = (zSig + roundIncrement) >> 10;
447 zSig &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven);
456 int16 aExp, bExp, zExp;
464 expDiff = aExp - bExp;
495 goto normalizeRoundAndPack;
510 normalizeRoundAndPack:
512 return normalizeRoundAndPackFloat32(zSign, zExp, zSig);
518 int16 aExp, bExp, zExp;
526 expDiff = aExp - bExp;
540 }
else if (expDiff < 0) {
557 zSig = 0x40000000 + aSig + bSig;
562 zSig = (aSig + bSig) << 1;
569 return roundAndPackFloat32(zSign, zExp, zSig);
579 if (aSign == bSign) {
580 return subFloat64Sigs(a, b, aSign);
582 return addFloat64Sigs(a, b, aSign);
593 if (aSign == bSign) {
594 return subFloat32Sigs(a, b, aSign);
596 return addFloat32Sigs(a, b, aSign);
607 if (aSign == bSign) {
608 return addFloat32Sigs(a, b, aSign);
610 return subFloat32Sigs(a, b, aSign);
621 if (aSign == bSign) {
622 return addFloat64Sigs(a, b, aSign);
624 return subFloat64Sigs(a, b, aSign);
633 shiftCount = countLeadingZeros64(aSig) - 11;
634 *zSigPtr = aSig << shiftCount;
635 *zExpPtr = 1 - shiftCount;
645 *z0Ptr = a0 + b0 + (z1 <
a1);
653 *z0Ptr = a0 - b0 - (a1 < b1);
659 bits64 rem0, rem1, term0, term1;
662 return LIT64(0xFFFFFFFFFFFFFFFF);
667 z = (b0 << 32 <=
a0) ?
LIT64(0xFFFFFFFF00000000) : tmp << 32;
669 sub128(a0, a1, term0, term1, &rem0, &rem1);
671 z -=
LIT64(0x100000000);
673 add128(rem0, rem1, b0, b1, &rem0, &rem1);
675 rem0 = (rem0 << 32) | (rem1 >> 32);
678 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : tmp;
684 bits32 aHigh, aLow, bHigh, bLow;
685 bits64 z0, zMiddleA, zMiddleB, z1;
691 z1 = ((
bits64) aLow) * bLow;
692 zMiddleA = ((
bits64) aLow) * bHigh;
693 zMiddleB = ((
bits64) aHigh) * bLow;
694 z0 = ((
bits64) aHigh) * bHigh;
695 zMiddleA += zMiddleB;
696 z0 += (((
bits64) (zMiddleA < zMiddleB)) << 32) + (zMiddleA >> 32);
699 z0 += (z1 < zMiddleA);
705 static void normalizeFloat32Subnormal(
bits32 aSig,
int16 * zExpPtr,
710 shiftCount = countLeadingZeros32(aSig) - 8;
711 *zSigPtr = aSig << shiftCount;
712 *zExpPtr = 1 - shiftCount;
718 flag aSign, bSign, zSign;
719 int16 aExp, bExp, zExp;
730 zSign = aSign ^ bSign;
741 if ((aExp | aSig) == 0) {
746 normalizeFloat64Subnormal(bSig, &bExp, &bSig);
751 normalizeFloat64Subnormal(aSig, &aExp, &aSig);
753 zExp = aExp - bExp + 0x3FD;
754 aSig = (aSig |
LIT64(0x0010000000000000)) << 10;
755 bSig = (bSig |
LIT64(0x0010000000000000)) << 11;
756 if (bSig <= (aSig + aSig)) {
760 zSig = estimateDiv128To64(aSig, 0, bSig);
761 if ((zSig & 0x1FF) <= 2) {
763 sub128(aSig, 0, term0, term1, &rem0, &rem1);
766 add128(rem0, rem1, 0, bSig, &rem0, &rem1);
770 return roundAndPackFloat64(zSign, zExp, zSig);
776 flag aSign, bSign, zSign;
777 int16 aExp, bExp, zExp;
787 zSign = aSign ^ bSign;
800 normalizeFloat32Subnormal(bSig, &bExp, &bSig);
805 normalizeFloat32Subnormal(aSig, &aExp, &aSig);
807 zExp = aExp - bExp + 0x7D;
808 aSig = (aSig | 0x00800000) << 7;
809 bSig = (bSig | 0x00800000) << 8;
810 if (bSig <= (aSig + aSig)) {
814 zSig = (((
bits64) aSig) << 32);
817 if ((zSig & 0x3F) == 0) {
818 zSig |= (((
bits64) bSig) * zSig != ((
bits64) aSig) << 32);
820 return roundAndPackFloat32(zSign, zExp, (
bits32)zSig);
826 char aSign, bSign, zSign;
827 int aExp, bExp, zExp;
828 unsigned int aSig, bSig;
829 unsigned long long zSig64;
838 zSign = aSign ^ bSign;
842 normalizeFloat32Subnormal(aSig, &aExp, &aSig);
847 normalizeFloat32Subnormal(bSig, &bExp, &bSig);
849 if ((bExp == 0xff && bSig == 0) || (aExp == 0xff && aSig == 0))
850 return roundAndPackFloat32(zSign, 0xff, 0);
852 zExp = aExp + bExp - 0x7F;
853 aSig = (aSig | 0x00800000) << 7;
854 bSig = (bSig | 0x00800000) << 8;
857 if (0 <= (
signed int)(zSig << 1)) {
861 return roundAndPackFloat32(zSign, zExp, zSig);
867 char aSign, bSign, zSign;
868 int aExp, bExp, zExp;
869 unsigned long long int aSig, bSig, zSig0, zSig1;
877 zSign = aSign ^ bSign;
882 normalizeFloat64Subnormal(aSig, &aExp, &aSig);
887 normalizeFloat64Subnormal(bSig, &bExp, &bSig);
889 if ((aExp == 0x7ff && aSig == 0) || (bExp == 0x7ff && bSig == 0))
890 return roundAndPackFloat64(zSign, 0x7ff, 0);
892 zExp = aExp + bExp - 0x3FF;
893 aSig = (aSig | 0x0010000000000000
LL) << 10;
894 bSig = (bSig | 0x0010000000000000
LL) << 11;
896 zSig0 |= (zSig1 != 0);
897 if (0 <= (
signed long long int)(zSig0 << 1)) {
901 return roundAndPackFloat64(zSign, zExp, zSig0);
925 if ( aExp || zSig ) {
929 return roundAndPackFloat32(aSign, aExp, zSig);