1 //===-- int_lib.h - configuration header for compiler-rt -----------------===//
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
7 //===----------------------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
19 #include "int_endianness.h"
21 // si_int is defined in Linux sysroot's asm-generic/siginfo.h
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
34 #error could not determine appropriate clzsi macro for this system
37 typedef int64_t di_int
;
38 typedef uint64_t du_int
;
43 #if _YUGA_LITTLE_ENDIAN
49 #endif // _YUGA_LITTLE_ENDIAN
56 #if _YUGA_LITTLE_ENDIAN
62 #endif // _YUGA_LITTLE_ENDIAN
66 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \
67 defined(__SIZEOF_INT128__) || defined(_WIN64)
68 #define CRT_HAS_128BIT
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__)
79 typedef int ti_int
__attribute__((mode(TI
)));
80 typedef unsigned tu_int
__attribute__((mode(TI
)));
85 #if _YUGA_LITTLE_ENDIAN
91 #endif // _YUGA_LITTLE_ENDIAN
98 #if _YUGA_LITTLE_ENDIAN
104 #endif // _YUGA_LITTLE_ENDIAN
108 static __inline ti_int
make_ti(di_int h
, di_int l
) {
110 r
.s
.high
= (du_int
)h
;
115 static __inline tu_int
make_tu(du_int h
, du_int l
) {
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
129 #define CRT_HAS_FLOATING_POINT 1
132 #if CRT_HAS_FLOATING_POINT
144 #if _YUGA_LITTLE_ENDIAN
150 #endif // _YUGA_LITTLE_ENDIAN
153 // Check if the target supports 80 bit extended precision long doubles.
154 // Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
155 // still makes it 80 bits. Clang will match whatever compiler it is trying to
156 // be compatible with. On 32-bit x86 Android, long double is 64 bits, while on
157 // x86_64 Android, long double is 128 bits.
158 #if (defined(__i386__) || defined(__x86_64__)) && \
159 !(defined(_MSC_VER) || defined(__ANDROID__))
160 #define HAS_80_BIT_LONG_DOUBLE 1
161 #elif defined(__m68k__) || defined(__ia64__)
162 #define HAS_80_BIT_LONG_DOUBLE 1
164 #define HAS_80_BIT_LONG_DOUBLE 0
167 #if HAS_80_BIT_LONG_DOUBLE
168 typedef long double xf_float
;
176 // From https://gcc.gnu.org/wiki/Ieee128PowerPC:
177 // PowerPC64 uses the following suffixes:
178 // IFmode: IBM extended double
179 // KFmode: IEEE 128-bit floating point
180 // TFmode: Matches the default for long double. With -mabi=ieeelongdouble,
181 // it is IEEE 128-bit, with -mabi=ibmlongdouble IBM extended double
182 // Since compiler-rt only implements the tf set of libcalls, we use long double
183 // for the tf_float typedef.
184 typedef long double tf_float
;
185 #define CRT_LDBL_128BIT
187 #if __LDBL_MANT_DIG__ == 113 && !defined(__LONG_DOUBLE_IBM128__)
188 #define CRT_HAS_IEEE_TF
189 #define CRT_LDBL_IEEE_F128
192 #elif __LDBL_MANT_DIG__ == 113 || \
193 (__FLT_RADIX__ == 16 && __LDBL_MANT_DIG__ == 28)
194 // Use long double instead of __float128 if it matches the IEEE 128-bit format
195 // or the IBM hexadecimal format.
196 #define CRT_LDBL_128BIT
198 #if __LDBL_MANT_DIG__ == 113
199 #define CRT_HAS_IEEE_TF
200 #define CRT_LDBL_IEEE_F128
202 typedef long double tf_float
;
204 #elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
205 #define CRT_HAS___FLOAT128_KEYWORD
207 // NB: we assume the __float128 type uses IEEE representation.
208 #define CRT_HAS_IEEE_TF
209 typedef __float128 tf_float
;
220 // __(u)int128_t is currently needed to compile the *tf builtins as we would
221 // otherwise need to manually expand the bit manipulation on two 64-bit value.
222 #if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
223 #define CRT_HAS_TF_MODE
226 #if __STDC_VERSION__ >= 199901L
227 typedef float _Complex Fcomplex
;
228 typedef double _Complex Dcomplex
;
229 typedef long double _Complex Lcomplex
;
230 #if defined(CRT_LDBL_128BIT)
231 typedef Lcomplex Qcomplex
;
232 #define CRT_HAS_NATIVE_COMPLEX_F128
233 #elif defined(CRT_HAS___FLOAT128_KEYWORD)
234 #if defined(__clang_major__) && __clang_major__ > 10
235 // Clang prior to 11 did not support __float128 _Complex.
236 typedef __float128 _Complex Qcomplex
;
237 #define CRT_HAS_NATIVE_COMPLEX_F128
238 #elif defined(__GNUC__) && __GNUC__ >= 7
239 // GCC does not allow __float128 _Complex, but accepts _Float128 _Complex.
240 typedef _Float128 _Complex Qcomplex
;
241 #define CRT_HAS_NATIVE_COMPLEX_F128
245 #define COMPLEX_REAL(x) __real__(x)
246 #define COMPLEX_IMAGINARY(x) __imag__(x)
249 float real
, imaginary
;
253 double real
, imaginary
;
257 long double real
, imaginary
;
260 #define COMPLEX_REAL(x) (x).real
261 #define COMPLEX_IMAGINARY(x) (x).imaginary
264 #ifdef CRT_HAS_NATIVE_COMPLEX_F128
265 #define COMPLEXTF_REAL(x) __real__(x)
266 #define COMPLEXTF_IMAGINARY(x) __imag__(x)
267 #elif defined(CRT_HAS_F128)
269 tf_float real
, imaginary
;
271 #define COMPLEXTF_REAL(x) (x).real
272 #define COMPLEXTF_IMAGINARY(x) (x).imaginary
275 #endif // CRT_HAS_FLOATING_POINT
276 #endif // INT_TYPES_H