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.
10 //
11 // This file defines various standard types, most importantly a number of unions
12 // used to access parts of larger types.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef INT_TYPES_H
17 #define INT_TYPES_H
18
19 #include "int_endianness.h"
20
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
36
37 typedef int64_t di_int;
38 typedef uint64_t du_int;
39
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;
52
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;
65
66 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \
67 defined(__riscv) || defined(_WIN64)
68 #define CRT_HAS_128BIT
69 #endif
70
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
77
78 #ifdef CRT_HAS_128BIT
79 typedef int ti_int __attribute__((mode(TI)));
80 typedef unsigned tu_int __attribute__((mode(TI)));
81
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;
94
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;
107
make_ti(di_int h,di_int l)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;
113 }
114
make_tu(du_int h,du_int l)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;
120 }
121
122 #endif // CRT_HAS_128BIT
123
124 typedef union {
125 su_int u;
126 float f;
127 } float_bits;
128
129 typedef union {
130 udwords u;
131 double f;
132 } double_bits;
133
134 typedef struct {
135 #if _YUGA_LITTLE_ENDIAN
136 udwords low;
137 udwords high;
138 #else
139 udwords high;
140 udwords low;
141 #endif // _YUGA_LITTLE_ENDIAN
142 } uqwords;
143
144 // Check if the target supports 80 bit extended precision long doubles.
145 // Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
146 // still makes it 80 bits. Clang will match whatever compiler it is trying to
147 // be compatible with. On 32-bit x86 Android, long double is 64 bits, while on
148 // x86_64 Android, long double is 128 bits.
149 #if (defined(__i386__) || defined(__x86_64__)) && \
150 !(defined(_MSC_VER) || defined(__ANDROID__))
151 #define HAS_80_BIT_LONG_DOUBLE 1
152 #elif defined(__m68k__) || defined(__ia64__)
153 #define HAS_80_BIT_LONG_DOUBLE 1
154 #else
155 #define HAS_80_BIT_LONG_DOUBLE 0
156 #endif
157
158 typedef union {
159 uqwords u;
160 long double f;
161 } long_double_bits;
162
163 #if __STDC_VERSION__ >= 199901L
164 typedef float _Complex Fcomplex;
165 typedef double _Complex Dcomplex;
166 typedef long double _Complex Lcomplex;
167
168 #define COMPLEX_REAL(x) __real__(x)
169 #define COMPLEX_IMAGINARY(x) __imag__(x)
170 #else
171 typedef struct {
172 float real, imaginary;
173 } Fcomplex;
174
175 typedef struct {
176 double real, imaginary;
177 } Dcomplex;
178
179 typedef struct {
180 long double real, imaginary;
181 } Lcomplex;
182
183 #define COMPLEX_REAL(x) (x).real
184 #define COMPLEX_IMAGINARY(x) (x).imaginary
185 #endif
186 #endif // INT_TYPES_H
187