2015-08-19 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / libquadmath / quadmath-imp.h
blob40b346b6ff22bd4028d0931f5b8ea576b4d57eda
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>
5 This file is part of the libquadmath library.
6 Libquadmath is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 Libquadmath is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with libquadmath; see the file COPYING.LIB. If
18 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 #ifndef QUADMATH_IMP_H
22 #define QUADMATH_IMP_H
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include "quadmath.h"
27 #include "config.h"
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. */
37 #define TININESS_AFTER_ROUNDING 1
40 /* Prototypes for internal functions. */
41 extern int32_t __quadmath_rem_pio2q (__float128, __float128 *);
42 extern void __quadmath_kernel_sincosq (__float128, __float128, __float128 *,
43 __float128 *, int);
44 extern __float128 __quadmath_kernel_sinq (__float128, __float128, int);
45 extern __float128 __quadmath_kernel_cosq (__float128, __float128);
46 extern __float128 __quadmath_x2y2m1q (__float128 x, __float128 y);
47 extern int __quadmath_isinf_nsq (__float128 x);
53 /* Frankly, if you have __float128, you have 64-bit integers, right? */
54 #ifndef UINT64_C
55 # error "No way!"
56 #endif
59 /* Main union type we use to manipulate the floating-point type. */
60 typedef union
62 __float128 value;
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
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;
84 struct
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;
95 struct
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;
110 struct
111 #ifdef __MINGW32__
112 /* Make sure we are using gnu-style bitfield handling. */
113 __attribute__ ((gcc_struct))
114 #endif
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;
131 } ieee854_float128;
134 /* Get two 64 bit ints from a long double. */
135 #define GET_FLT128_WORDS64(ix0,ix1,d) \
136 do { \
137 ieee854_float128 u; \
138 u.value = (d); \
139 (ix0) = u.words64.high; \
140 (ix1) = u.words64.low; \
141 } while (0)
143 /* Set a long double from two 64 bit ints. */
144 #define SET_FLT128_WORDS64(d,ix0,ix1) \
145 do { \
146 ieee854_float128 u; \
147 u.words64.high = (ix0); \
148 u.words64.low = (ix1); \
149 (d) = u.value; \
150 } while (0)
152 /* Get the more significant 64 bits of a long double mantissa. */
153 #define GET_FLT128_MSW64(v,d) \
154 do { \
155 ieee854_float128 u; \
156 u.value = (d); \
157 (v) = u.words64.high; \
158 } while (0)
160 /* Set the more significant 64 bits of a long double mantissa from an int. */
161 #define SET_FLT128_MSW64(d,v) \
162 do { \
163 ieee854_float128 u; \
164 u.value = (d); \
165 u.words64.high = (v); \
166 (d) = u.value; \
167 } while (0)
169 /* Get the least significant 64 bits of a long double mantissa. */
170 #define GET_FLT128_LSW64(v,d) \
171 do { \
172 ieee854_float128 u; \
173 u.value = (d); \
174 (v) = u.words64.low; \
175 } while (0)
178 #define IEEE854_FLOAT128_BIAS 0x3fff
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)
189 #endif