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