1 /* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
2  *
3  *                     The LLVM Compiler Infrastructure
4  *
5  * This file is dual licensed under the MIT and the University of Illinois Open
6  * Source Licenses. See LICENSE.TXT for details.
7  *
8  * ===----------------------------------------------------------------------===
9  *
10  * This file is not part of the interface of this library.
11  *
12  * This file defines various standard types, most importantly a number of unions
13  * used to access parts of larger types.
14  *
15  * ===----------------------------------------------------------------------===
16  */
17 
18 #ifndef INT_TYPES_H
19 #define INT_TYPES_H
20 
21 #include "int_endianness.h"
22 
23 /* si_int is defined in Linux sysroot's asm-generic/siginfo.h */
24 #ifdef si_int
25 #undef si_int
26 #endif
27 typedef      int si_int;
28 typedef unsigned su_int;
29 
30 typedef          long long di_int;
31 typedef unsigned long long du_int;
32 
33 typedef union
34 {
35     di_int all;
36     struct
37     {
38 #if _YUGA_LITTLE_ENDIAN
39         su_int low;
40         si_int high;
41 #else
42         si_int high;
43         su_int low;
44 #endif /* _YUGA_LITTLE_ENDIAN */
45     }s;
46 } dwords;
47 
48 typedef union
49 {
50     du_int all;
51     struct
52     {
53 #if _YUGA_LITTLE_ENDIAN
54         su_int low;
55         su_int high;
56 #else
57         su_int high;
58         su_int low;
59 #endif /* _YUGA_LITTLE_ENDIAN */
60     }s;
61 } udwords;
62 
63 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) ||             \
64     defined(__riscv) || defined(_WIN64)
65 #define CRT_HAS_128BIT
66 #endif
67 
68 /* MSVC doesn't have a working 128bit integer type. Users should really compile
69  * compiler-rt with clang, but if they happen to be doing a standalone build for
70  * asan or something else, disable the 128 bit parts so things sort of work.
71  */
72 #if defined(_MSC_VER) && !defined(__clang__)
73 #undef CRT_HAS_128BIT
74 #endif
75 
76 #ifdef CRT_HAS_128BIT
77 typedef int      ti_int __attribute__ ((mode (TI)));
78 typedef unsigned tu_int __attribute__ ((mode (TI)));
79 
80 typedef union
81 {
82     ti_int all;
83     struct
84     {
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 {
97     tu_int all;
98     struct
99     {
100 #if _YUGA_LITTLE_ENDIAN
101         du_int low;
102         du_int high;
103 #else
104         du_int high;
105         du_int low;
106 #endif /* _YUGA_LITTLE_ENDIAN */
107     }s;
108 } utwords;
109 
make_ti(di_int h,di_int l)110 static __inline ti_int make_ti(di_int h, di_int l) {
111     twords r;
112     r.s.high = h;
113     r.s.low = l;
114     return r.all;
115 }
116 
make_tu(du_int h,du_int l)117 static __inline tu_int make_tu(du_int h, du_int l) {
118     utwords r;
119     r.s.high = h;
120     r.s.low = l;
121     return r.all;
122 }
123 
124 #endif /* CRT_HAS_128BIT */
125 
126 typedef union
127 {
128     su_int u;
129     float f;
130 } float_bits;
131 
132 typedef union
133 {
134     udwords u;
135     double  f;
136 } double_bits;
137 
138 typedef struct
139 {
140 #if _YUGA_LITTLE_ENDIAN
141     udwords low;
142     udwords high;
143 #else
144     udwords high;
145     udwords low;
146 #endif /* _YUGA_LITTLE_ENDIAN */
147 } uqwords;
148 
149 /* Check if the target supports 80 bit extended precision long doubles.
150  * Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
151  * still makes it 80 bits. Clang will match whatever compiler it is trying to
152  * be compatible with.
153  */
154 #if ((defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)) || \
155     defined(__m68k__) || defined(__ia64__)
156 #define HAS_80_BIT_LONG_DOUBLE 1
157 #else
158 #define HAS_80_BIT_LONG_DOUBLE 0
159 #endif
160 
161 typedef union
162 {
163     uqwords     u;
164     long double f;
165 } long_double_bits;
166 
167 #if __STDC_VERSION__ >= 199901L
168 typedef float _Complex Fcomplex;
169 typedef double _Complex Dcomplex;
170 typedef long double _Complex Lcomplex;
171 
172 #define COMPLEX_REAL(x) __real__(x)
173 #define COMPLEX_IMAGINARY(x) __imag__(x)
174 #else
175 typedef struct { float real, imaginary; } Fcomplex;
176 
177 typedef struct { double real, imaginary; } Dcomplex;
178 
179 typedef struct { long double real, imaginary; } Lcomplex;
180 
181 #define COMPLEX_REAL(x) (x).real
182 #define COMPLEX_IMAGINARY(x) (x).imaginary
183 #endif
184 #endif /* INT_TYPES_H */
185 
186