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
25typedef int si_int;
26typedef unsigned su_int;
27
28typedef long long di_int;
29typedef unsigned long long du_int;
30
31typedef 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
44typedef 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
70typedef int ti_int __attribute__((mode(TI)));
71typedef unsigned tu_int __attribute__((mode(TI)));
72
73typedef 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
86typedef 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
99static __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
106static __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
116typedef union {
117  su_int u;
118  float f;
119} float_bits;
120
121typedef union {
122  udwords u;
123  double f;
124} double_bits;
125#endif
126
127typedef 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
149typedef union {
150  uqwords u;
151  long double f;
152} long_double_bits;
153
154#if __STDC_VERSION__ >= 199901L
155typedef float _Complex Fcomplex;
156typedef double _Complex Dcomplex;
157typedef long double _Complex Lcomplex;
158
159#define COMPLEX_REAL(x) __real__(x)
160#define COMPLEX_IMAGINARY(x) __imag__(x)
161#else
162typedef struct {
163  float real, imaginary;
164} Fcomplex;
165
166typedef struct {
167  double real, imaginary;
168} Dcomplex;
169
170typedef 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
179