12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===//
22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//                     The LLVM Compiler Infrastructure
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is dual licensed under the MIT and the University of Illinois Open
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Source Licenses. See LICENSE.TXT for details.
72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===//
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is a configuration header for soft-float routines in compiler-rt.
112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file does not provide any part of the compiler-rt interface, but defines
122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// many useful constants and utility routines that are used in the
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// implementation of the soft-float routines in compiler-rt.
142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Assumes that float, double and long double correspond to the IEEE-754
162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// binary32, binary64 and binary 128 types, respectively, and that integer
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// endianness matches floating point endianness on the target platform.
182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===//
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef FP_LIB_HEADER
222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define FP_LIB_HEADER
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdint.h>
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdbool.h>
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <limits.h>
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "int_lib.h"
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in
305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// 32-bit mode.
315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if defined(__FreeBSD__) && defined(__i386__)
325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# include <sys/param.h>
335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# if __FreeBSD_version < 903000  // v9.3
345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  define uint64_t unsigned long long
355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  define int64_t long long
365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  undef UINT64_C
375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  define UINT64_C(c) (c ## ULL)
385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# endif
395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
405d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined SINGLE_PRECISION
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef uint32_t rep_t;
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef int32_t srep_t;
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef float fp_t;
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define REP_C UINT32_C
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define significandBits 23
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline int rep_clz(rep_t a) {
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return __builtin_clz(a);
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32x32 --> 64 bit multiply
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product = (uint64_t)a*b;
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *hi = product >> 32;
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *lo = product;
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b);
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined DOUBLE_PRECISION
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef uint64_t rep_t;
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef int64_t srep_t;
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef double fp_t;
662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define REP_C UINT64_C
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define significandBits 52
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline int rep_clz(rep_t a) {
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined __LP64__
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return __builtin_clzl(a);
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (a & REP_C(0xffffffff00000000))
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return __builtin_clz(a >> 32);
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    else
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return 32 + __builtin_clz(a & REP_C(0xffffffff));
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define loWord(a) (a & 0xffffffffU)
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define hiWord(a) (a >> 32)
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// many 64-bit platforms have this operation, but they tend to have hardware
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// floating-point, so we don't bother with a special case for them here.
862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Each of the component 32x32 -> 64 products
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t plolo = loWord(a) * loWord(b);
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t plohi = loWord(a) * hiWord(b);
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t philo = hiWord(a) * loWord(b);
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t phihi = hiWord(a) * hiWord(b);
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Sum terms that contribute to lo in a way that allows us to get the carry
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t r0 = loWord(plolo);
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *lo = r0 + (r1 << 32);
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Sum terms contributing to hi with the carry from lo
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef loWord
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef hiWord
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#elif defined QUAD_PRECISION
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if __LDBL_MANT_DIG__ == 113
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define CRT_LDBL_128BIT
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef __uint128_t rep_t;
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef __int128_t srep_t;
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef long double fp_t;
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define REP_C (__uint128_t)
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Note: Since there is no explicit way to tell compiler the constant is a
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 128-bit integer, we let the constant be casted to 128-bit integer
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define significandBits 112
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline int rep_clz(rep_t a) {
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const union
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        {
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             __uint128_t ll;
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if _YUGA_BIG_ENDIAN
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             struct { uint64_t high, low; } s;
1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             struct { uint64_t low, high; } s;
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        } uu = { .ll = a };
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    uint64_t word;
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    uint64_t add;
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (uu.s.high){
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        word = uu.s.high;
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        add = 0;
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    else{
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        word = uu.s.low;
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        add = 64;
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return __builtin_clzll(word) + add;
1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_LoMask   UINT64_C(0x00000000ffffffff)
1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_HiMask   UINT64_C(0xffffffff00000000)
1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_FullMask UINT64_C(0xffffffffffffffff)
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask)
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask)
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask)
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define Word_4(a) (uint64_t)(a & Word_LoMask)
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 128x128 -> 256 wide multiply for platforms that don't have such an operation;
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// many 64-bit platforms have this operation, but they tend to have hardware
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// floating-point, so we don't bother with a special case for them here.
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product11 = Word_1(a) * Word_1(b);
1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product12 = Word_1(a) * Word_2(b);
1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product13 = Word_1(a) * Word_3(b);
1562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product14 = Word_1(a) * Word_4(b);
1572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product21 = Word_2(a) * Word_1(b);
1582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product22 = Word_2(a) * Word_2(b);
1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product23 = Word_2(a) * Word_3(b);
1602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product24 = Word_2(a) * Word_4(b);
1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product31 = Word_3(a) * Word_1(b);
1622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product32 = Word_3(a) * Word_2(b);
1632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product33 = Word_3(a) * Word_3(b);
1642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product34 = Word_3(a) * Word_4(b);
1652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product41 = Word_4(a) * Word_1(b);
1662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product42 = Word_4(a) * Word_2(b);
1672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product43 = Word_4(a) * Word_3(b);
1682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const uint64_t product44 = Word_4(a) * Word_4(b);
1692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum0 = (__uint128_t)product44;
1712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum1 = (__uint128_t)product34 +
1722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product43;
1732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum2 = (__uint128_t)product24 +
1742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product33 +
1752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product42;
1762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum3 = (__uint128_t)product14 +
1772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product23 +
1782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product32 +
1792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product41;
1802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum4 = (__uint128_t)product13 +
1812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product22 +
1822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product31;
1832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum5 = (__uint128_t)product12 +
1842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                             (__uint128_t)product21;
1852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t sum6 = (__uint128_t)product11;
1862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t r0 = (sum0 & Word_FullMask) +
1882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           ((sum1 & Word_LoMask) << 32);
1892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const __uint128_t r1 = (sum0 >> 64) +
1902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           ((sum1 >> 32) & Word_FullMask) +
1912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           (sum2 & Word_FullMask) +
1922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           ((sum3 << 32) & Word_HiMask);
1932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *lo = r0 + (r1 << 64);
1952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *hi = (r1 >> 64) +
1962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          (sum1 >> 96) +
1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          (sum2 >> 64) +
1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          (sum3 >> 32) +
1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          sum4 +
2002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          (sum5 << 32) +
2012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          (sum6 << 64);
2022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_1
2042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_2
2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_3
2062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_4
2072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_HiMask
2082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_LoMask
2092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef Word_FullMask
2102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // __LDBL_MANT_DIG__ == 113
2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
2122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
2132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
2142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || defined(CRT_LDBL_128BIT)
2162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define typeWidth       (sizeof(rep_t)*CHAR_BIT)
2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define exponentBits    (typeWidth - significandBits - 1)
2182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define maxExponent     ((1 << exponentBits) - 1)
2192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define exponentBias    (maxExponent >> 1)
2202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define implicitBit     (REP_C(1) << significandBits)
2222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define significandMask (implicitBit - 1U)
2232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define signBit         (REP_C(1) << (significandBits + exponentBits))
2242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define absMask         (signBit - 1U)
2252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define exponentMask    (absMask ^ significandMask)
2262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define oneRep          ((rep_t)exponentBias << significandBits)
2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define infRep          exponentMask
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define quietBit        (implicitBit >> 1)
2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define qnanRep         (exponentMask | quietBit)
2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline rep_t toRep(fp_t x) {
2322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const union { fp_t f; rep_t i; } rep = {.f = x};
2332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return rep.i;
2342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline fp_t fromRep(rep_t x) {
2372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const union { fp_t f; rep_t i; } rep = {.i = x};
2382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return rep.f;
2392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline int normalize(rep_t *significand) {
2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const int shift = rep_clz(*significand) - rep_clz(implicitBit);
2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *significand <<= shift;
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return 1 - shift;
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) {
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *hi = *hi << count | *lo >> (typeWidth - count);
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    *lo = *lo << count;
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) {
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (count < typeWidth) {
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        const bool sticky = *lo << (typeWidth - count);
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *lo = *hi << (typeWidth - count) | *lo >> count | sticky;
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *hi = *hi >> count;
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    else if (count < 2*typeWidth) {
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        const bool sticky = *hi << (2*typeWidth - count) | *lo;
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *lo = *hi >> (count - typeWidth) | sticky;
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *hi = 0;
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        const bool sticky = *hi | *lo;
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *lo = sticky;
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *hi = 0;
2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // FP_LIB_HEADER
271