]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/int_types.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / builtins / int_types.h
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 int si_int;
26 typedef unsigned su_int;
27
28 typedef long long di_int;
29 typedef unsigned long long du_int;
30
31 typedef union {
32   di_int all;
33   struct {
34 #if _YUGA_LITTLE_ENDIAN
35     su_int low;
36     si_int high;
37 #else
38     si_int high;
39     su_int low;
40 #endif // _YUGA_LITTLE_ENDIAN
41   } s;
42 } dwords;
43
44 typedef union {
45   du_int all;
46   struct {
47 #if _YUGA_LITTLE_ENDIAN
48     su_int low;
49     su_int high;
50 #else
51     su_int high;
52     su_int low;
53 #endif // _YUGA_LITTLE_ENDIAN
54   } s;
55 } udwords;
56
57 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) ||             \
58     defined(__riscv) || defined(_WIN64)
59 #define CRT_HAS_128BIT
60 #endif
61
62 // MSVC doesn't have a working 128bit integer type. Users should really compile
63 // compiler-rt with clang, but if they happen to be doing a standalone build for
64 // asan or something else, disable the 128 bit parts so things sort of work.
65 #if defined(_MSC_VER) && !defined(__clang__)
66 #undef CRT_HAS_128BIT
67 #endif
68
69 #ifdef CRT_HAS_128BIT
70 typedef int ti_int __attribute__((mode(TI)));
71 typedef unsigned tu_int __attribute__((mode(TI)));
72
73 typedef union {
74   ti_int all;
75   struct {
76 #if _YUGA_LITTLE_ENDIAN
77     du_int low;
78     di_int high;
79 #else
80     di_int high;
81     du_int low;
82 #endif // _YUGA_LITTLE_ENDIAN
83   } s;
84 } twords;
85
86 typedef union {
87   tu_int all;
88   struct {
89 #if _YUGA_LITTLE_ENDIAN
90     du_int low;
91     du_int high;
92 #else
93     du_int high;
94     du_int low;
95 #endif // _YUGA_LITTLE_ENDIAN
96   } s;
97 } utwords;
98
99 static __inline ti_int make_ti(di_int h, di_int l) {
100   twords r;
101   r.s.high = h;
102   r.s.low = l;
103   return r.all;
104 }
105
106 static __inline tu_int make_tu(du_int h, du_int l) {
107   utwords r;
108   r.s.high = h;
109   r.s.low = l;
110   return r.all;
111 }
112
113 #endif // CRT_HAS_128BIT
114
115 #ifndef _STANDALONE
116 typedef union {
117   su_int u;
118   float f;
119 } float_bits;
120
121 typedef union {
122   udwords u;
123   double f;
124 } double_bits;
125 #endif
126
127 typedef struct {
128 #if _YUGA_LITTLE_ENDIAN
129   udwords low;
130   udwords high;
131 #else
132   udwords high;
133   udwords low;
134 #endif // _YUGA_LITTLE_ENDIAN
135 } uqwords;
136
137 // Check if the target supports 80 bit extended precision long doubles.
138 // Notably, on x86 Windows, MSVC only provides a 64-bit long double, but GCC
139 // still makes it 80 bits. Clang will match whatever compiler it is trying to
140 // be compatible with.
141 #if ((defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)) ||      \
142     defined(__m68k__) || defined(__ia64__)
143 #define HAS_80_BIT_LONG_DOUBLE 1
144 #else
145 #define HAS_80_BIT_LONG_DOUBLE 0
146 #endif
147
148 #ifndef _STANDALONE
149 typedef union {
150   uqwords u;
151   long double f;
152 } long_double_bits;
153
154 #if __STDC_VERSION__ >= 199901L
155 typedef float _Complex Fcomplex;
156 typedef double _Complex Dcomplex;
157 typedef long double _Complex Lcomplex;
158
159 #define COMPLEX_REAL(x) __real__(x)
160 #define COMPLEX_IMAGINARY(x) __imag__(x)
161 #else
162 typedef struct {
163   float real, imaginary;
164 } Fcomplex;
165
166 typedef struct {
167   double real, imaginary;
168 } Dcomplex;
169
170 typedef struct {
171   long double real, imaginary;
172 } Lcomplex;
173
174 #define COMPLEX_REAL(x) (x).real
175 #define COMPLEX_IMAGINARY(x) (x).imaginary
176 #endif
177 #endif
178 #endif // INT_TYPES_H