1/* GCC Quad-Precision Math Library 2 Copyright (C) 2010, 2011 Free Software Foundation, Inc. 3 Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 4 5This file is part of the libquadmath library. 6Libquadmath is free software; you can redistribute it and/or 7modify it under the terms of the GNU Library General Public 8License as published by the Free Software Foundation; either 9version 2 of the License, or (at your option) any later version. 10 11Libquadmath is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14Library General Public License for more details. 15 16You should have received a copy of the GNU Library General Public 17License along with libquadmath; see the file COPYING.LIB. If 18not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 19Boston, MA 02110-1301, USA. */ 20 21#ifndef QUADMATH_IMP_H 22#define QUADMATH_IMP_H 23 24#include <stdint.h> 25#include <stdlib.h> 26#include "quadmath.h" 27#include "config.h" 28 29 30/* Under IEEE 754, an architecture may determine tininess of 31 floating-point results either "before rounding" or "after 32 rounding", but must do so in the same way for all operations 33 returning binary results. Define TININESS_AFTER_ROUNDING to 1 for 34 "after rounding" architectures, 0 for "before rounding" 35 architectures. */ 36 37#define TININESS_AFTER_ROUNDING 1 38 39 40/* Prototypes for internal functions. */ 41extern int32_t __quadmath_rem_pio2q (__float128, __float128 *); 42extern void __quadmath_kernel_sincosq (__float128, __float128, __float128 *, 43 __float128 *, int); 44extern __float128 __quadmath_kernel_sinq (__float128, __float128, int); 45extern __float128 __quadmath_kernel_cosq (__float128, __float128); 46extern __float128 __quadmath_x2y2m1q (__float128 x, __float128 y); 47extern int __quadmath_isinf_nsq (__float128 x); 48 49 50 51 52 53/* Frankly, if you have __float128, you have 64-bit integers, right? */ 54#ifndef UINT64_C 55# error "No way!" 56#endif 57 58 59/* Main union type we use to manipulate the floating-point type. */ 60typedef union 61{ 62 __float128 value; 63 64 struct 65#ifdef __MINGW32__ 66 /* On mingw targets the ms-bitfields option is active by default. 67 Therefore enforce gnu-bitfield style. */ 68 __attribute__ ((gcc_struct)) 69#endif 70 { 71#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 72 unsigned negative:1; 73 unsigned exponent:15; 74 uint64_t mant_high:48; 75 uint64_t mant_low:64; 76#else 77 uint64_t mant_low:64; 78 uint64_t mant_high:48; 79 unsigned exponent:15; 80 unsigned negative:1; 81#endif 82 } ieee; 83 84 struct 85 { 86#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 87 uint64_t high; 88 uint64_t low; 89#else 90 uint64_t low; 91 uint64_t high; 92#endif 93 } words64; 94 95 struct 96 { 97#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 98 uint32_t w0; 99 uint32_t w1; 100 uint32_t w2; 101 uint32_t w3; 102#else 103 uint32_t w3; 104 uint32_t w2; 105 uint32_t w1; 106 uint32_t w0; 107#endif 108 } words32; 109 110 struct 111#ifdef __MINGW32__ 112 /* Make sure we are using gnu-style bitfield handling. */ 113 __attribute__ ((gcc_struct)) 114#endif 115 { 116#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 117 unsigned negative:1; 118 unsigned exponent:15; 119 unsigned quiet_nan:1; 120 uint64_t mant_high:47; 121 uint64_t mant_low:64; 122#else 123 uint64_t mant_low:64; 124 uint64_t mant_high:47; 125 unsigned quiet_nan:1; 126 unsigned exponent:15; 127 unsigned negative:1; 128#endif 129 } nan; 130 131} ieee854_float128; 132 133 134/* Get two 64 bit ints from a long double. */ 135#define GET_FLT128_WORDS64(ix0,ix1,d) \ 136do { \ 137 ieee854_float128 u; \ 138 u.value = (d); \ 139 (ix0) = u.words64.high; \ 140 (ix1) = u.words64.low; \ 141} while (0) 142 143/* Set a long double from two 64 bit ints. */ 144#define SET_FLT128_WORDS64(d,ix0,ix1) \ 145do { \ 146 ieee854_float128 u; \ 147 u.words64.high = (ix0); \ 148 u.words64.low = (ix1); \ 149 (d) = u.value; \ 150} while (0) 151 152/* Get the more significant 64 bits of a long double mantissa. */ 153#define GET_FLT128_MSW64(v,d) \ 154do { \ 155 ieee854_float128 u; \ 156 u.value = (d); \ 157 (v) = u.words64.high; \ 158} while (0) 159 160/* Set the more significant 64 bits of a long double mantissa from an int. */ 161#define SET_FLT128_MSW64(d,v) \ 162do { \ 163 ieee854_float128 u; \ 164 u.value = (d); \ 165 u.words64.high = (v); \ 166 (d) = u.value; \ 167} while (0) 168 169/* Get the least significant 64 bits of a long double mantissa. */ 170#define GET_FLT128_LSW64(v,d) \ 171do { \ 172 ieee854_float128 u; \ 173 u.value = (d); \ 174 (v) = u.words64.low; \ 175} while (0) 176 177 178#define IEEE854_FLOAT128_BIAS 0x3fff 179 180#define QUADFP_NAN 0 181#define QUADFP_INFINITE 1 182#define QUADFP_ZERO 2 183#define QUADFP_SUBNORMAL 3 184#define QUADFP_NORMAL 4 185#define fpclassifyq(x) \ 186 __builtin_fpclassify (QUADFP_NAN, QUADFP_INFINITE, QUADFP_NORMAL, \ 187 QUADFP_SUBNORMAL, QUADFP_ZERO, x) 188 189#endif 190