Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / lib / builtins / int_types.h
blob18bf0a7f3bf993979c0ff5337ae78debb8d020f4
1 //===-- int_lib.h - configuration header for compiler-rt -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is not part of the interface of this library.
11 // This file defines various standard types, most importantly a number of unions
12 // used to access parts of larger types.
14 //===----------------------------------------------------------------------===//
16 #ifndef INT_TYPES_H
17 #define INT_TYPES_H
19 #include "int_endianness.h"
21 // si_int is defined in Linux sysroot's asm-generic/siginfo.h
22 #ifdef si_int
23 #undef si_int
24 #endif
25 typedef int32_t si_int;
26 typedef uint32_t su_int;
27 #if UINT_MAX == 0xFFFFFFFF
28 #define clzsi __builtin_clz
29 #define ctzsi __builtin_ctz
30 #elif ULONG_MAX == 0xFFFFFFFF
31 #define clzsi __builtin_clzl
32 #define ctzsi __builtin_ctzl
33 #else
34 #error could not determine appropriate clzsi macro for this system
35 #endif
37 typedef int64_t di_int;
38 typedef uint64_t du_int;
40 typedef union {
41 di_int all;
42 struct {
43 #if _YUGA_LITTLE_ENDIAN
44 su_int low;
45 si_int high;
46 #else
47 si_int high;
48 su_int low;
49 #endif // _YUGA_LITTLE_ENDIAN
50 } s;
51 } dwords;
53 typedef union {
54 du_int all;
55 struct {
56 #if _YUGA_LITTLE_ENDIAN
57 su_int low;
58 su_int high;
59 #else
60 su_int high;
61 su_int low;
62 #endif // _YUGA_LITTLE_ENDIAN
63 } s;
64 } udwords;
66 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \
67 defined(__SIZEOF_INT128__) || defined(_WIN64)
68 #define CRT_HAS_128BIT
69 #endif
71 // MSVC doesn't have a working 128bit integer type. Users should really compile
72 // compiler-rt with clang, but if they happen to be doing a standalone build for
73 // asan or something else, disable the 128 bit parts so things sort of work.
74 #if defined(_MSC_VER) && !defined(__clang__)
75 #undef CRT_HAS_128BIT
76 #endif
78 #ifdef CRT_HAS_128BIT
79 typedef int ti_int __attribute__((mode(TI)));
80 typedef unsigned tu_int __attribute__((mode(TI)));
82 typedef union {
83 ti_int all;
84 struct {
85 #if _YUGA_LITTLE_ENDIAN
86 du_int low;
87 di_int high;
88 #else
89 di_int high;
90 du_int low;
91 #endif // _YUGA_LITTLE_ENDIAN
92 } s;
93 } twords;
95 typedef union {
96 tu_int all;
97 struct {
98 #if _YUGA_LITTLE_ENDIAN
99 du_int low;
100 du_int high;
101 #else
102 du_int high;
103 du_int low;
104 #endif // _YUGA_LITTLE_ENDIAN
105 } s;
106 } utwords;
108 static __inline ti_int make_ti(di_int h, di_int l) {
109 twords r;
110 r.s.high = h;
111 r.s.low = l;
112 return r.all;
115 static __inline tu_int make_tu(du_int h, du_int l) {
116 utwords r;
117 r.s.high = h;
118 r.s.low = l;
119 return r.all;
122 #endif // CRT_HAS_128BIT
124 // FreeBSD's boot environment does not support using floating-point and poisons
125 // the float and double keywords.
126 #if defined(__FreeBSD__) && defined(_STANDALONE)
127 #define CRT_HAS_FLOATING_POINT 0
128 #else
129 #define CRT_HAS_FLOATING_POINT 1
130 #endif
132 #if CRT_HAS_FLOATING_POINT
133 typedef union {
134 su_int u;
135 float f;
136 } float_bits;
138 typedef union {
139 udwords u;
140 double f;
141 } double_bits;
142 #endif
144 typedef struct {
145 #if _YUGA_LITTLE_ENDIAN
146 udwords low;
147 udwords high;
148 #else
149 udwords high;
150 udwords low;
151 #endif // _YUGA_LITTLE_ENDIAN
152 } uqwords;
154 // Check if the target supports 80 bit extended precision long doubles.
155 // Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
156 // still makes it 80 bits. Clang will match whatever compiler it is trying to
157 // be compatible with. On 32-bit x86 Android, long double is 64 bits, while on
158 // x86_64 Android, long double is 128 bits.
159 #if (defined(__i386__) || defined(__x86_64__)) && \
160 !(defined(_MSC_VER) || defined(__ANDROID__))
161 #define HAS_80_BIT_LONG_DOUBLE 1
162 #elif defined(__m68k__) || defined(__ia64__)
163 #define HAS_80_BIT_LONG_DOUBLE 1
164 #else
165 #define HAS_80_BIT_LONG_DOUBLE 0
166 #endif
168 #if HAS_80_BIT_LONG_DOUBLE
169 typedef long double xf_float;
170 typedef union {
171 uqwords u;
172 xf_float f;
173 } xf_bits;
174 #endif
176 #ifdef __powerpc64__
177 // From https://gcc.gnu.org/wiki/Ieee128PowerPC:
178 // PowerPC64 uses the following suffixes:
179 // IFmode: IBM extended double
180 // KFmode: IEEE 128-bit floating point
181 // TFmode: Matches the default for long double. With -mabi=ieeelongdouble,
182 // it is IEEE 128-bit, with -mabi=ibmlongdouble IBM extended double
183 // Since compiler-rt only implements the tf set of libcalls, we use long double
184 // for the tf_float typedef.
185 typedef long double tf_float;
186 #define CRT_LDBL_128BIT
187 #define CRT_HAS_F128
188 #if __LDBL_MANT_DIG__ == 113 && !defined(__LONG_DOUBLE_IBM128__)
189 #define CRT_HAS_IEEE_TF
190 #define CRT_LDBL_IEEE_F128
191 #endif
192 #define TF_C(x) x##L
193 #elif __LDBL_MANT_DIG__ == 113
194 // Use long double instead of __float128 if it matches the IEEE 128-bit format.
195 #define CRT_LDBL_128BIT
196 #define CRT_HAS_F128
197 #define CRT_HAS_IEEE_TF
198 #define CRT_LDBL_IEEE_F128
199 typedef long double tf_float;
200 #define TF_C(x) x##L
201 #elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
202 #define CRT_HAS___FLOAT128_KEYWORD
203 #define CRT_HAS_F128
204 // NB: we assume the __float128 type uses IEEE representation.
205 #define CRT_HAS_IEEE_TF
206 typedef __float128 tf_float;
207 #define TF_C(x) x##Q
208 #endif
210 #ifdef CRT_HAS_F128
211 typedef union {
212 uqwords u;
213 tf_float f;
214 } tf_bits;
215 #endif
217 // __(u)int128_t is currently needed to compile the *tf builtins as we would
218 // otherwise need to manually expand the bit manipulation on two 64-bit value.
219 #if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
220 #define CRT_HAS_TF_MODE
221 #endif
223 #if CRT_HAS_FLOATING_POINT
224 #if __STDC_VERSION__ >= 199901L
225 typedef float _Complex Fcomplex;
226 typedef double _Complex Dcomplex;
227 typedef long double _Complex Lcomplex;
228 #if defined(CRT_LDBL_128BIT)
229 typedef Lcomplex Qcomplex;
230 #define CRT_HAS_NATIVE_COMPLEX_F128
231 #elif defined(CRT_HAS___FLOAT128_KEYWORD)
232 #if defined(__clang_major__) && __clang_major__ > 10
233 // Clang prior to 11 did not support __float128 _Complex.
234 typedef __float128 _Complex Qcomplex;
235 #define CRT_HAS_NATIVE_COMPLEX_F128
236 #elif defined(__GNUC__) && __GNUC__ >= 7
237 // GCC does not allow __float128 _Complex, but accepts _Float128 _Complex.
238 typedef _Float128 _Complex Qcomplex;
239 #define CRT_HAS_NATIVE_COMPLEX_F128
240 #endif
241 #endif
243 #define COMPLEX_REAL(x) __real__(x)
244 #define COMPLEX_IMAGINARY(x) __imag__(x)
245 #else
246 typedef struct {
247 float real, imaginary;
248 } Fcomplex;
250 typedef struct {
251 double real, imaginary;
252 } Dcomplex;
254 typedef struct {
255 long double real, imaginary;
256 } Lcomplex;
258 #define COMPLEX_REAL(x) (x).real
259 #define COMPLEX_IMAGINARY(x) (x).imaginary
260 #endif
262 #ifdef CRT_HAS_NATIVE_COMPLEX_F128
263 #define COMPLEXTF_REAL(x) __real__(x)
264 #define COMPLEXTF_IMAGINARY(x) __imag__(x)
265 #elif defined(CRT_HAS_F128)
266 typedef struct {
267 tf_float real, imaginary;
268 } Qcomplex;
269 #define COMPLEXTF_REAL(x) (x).real
270 #define COMPLEXTF_IMAGINARY(x) (x).imaginary
271 #endif
273 #endif
274 #endif // INT_TYPES_H