Commit | Line | Data |
---|---|---|
90702366 | 1 | /* SPDX-License-Identifier: MIT */ |
f2d7b530 MJ |
2 | /* SPDX-FileCopyrightText: 2021 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> */ |
3 | ||
dd76f2d6 MD |
4 | /* |
5 | * rseq/compiler.h | |
6 | * | |
7 | * Work-around asm goto compiler bugs. | |
dd76f2d6 MD |
8 | */ |
9 | ||
10 | #ifndef RSEQ_COMPILER_H | |
11 | #define RSEQ_COMPILER_H | |
12 | ||
d292e9e1 MD |
13 | #if defined __cplusplus |
14 | # include <type_traits> /* for std::remove_cv */ | |
15 | #endif | |
16 | ||
dd76f2d6 MD |
17 | /* |
18 | * gcc prior to 4.8.2 miscompiles asm goto. | |
19 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 | |
20 | * | |
21 | * gcc prior to 8.1.0 miscompiles asm goto at O1. | |
22 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908 | |
23 | * | |
24 | * clang prior to version 13.0.1 miscompiles asm goto at O2. | |
25 | * https://github.com/llvm/llvm-project/issues/52735 | |
26 | * | |
27 | * Work around these issues by adding a volatile inline asm with | |
28 | * memory clobber in the fallthrough after the asm goto and at each | |
29 | * label target. Emit this for all compilers in case other similar | |
30 | * issues are found in the future. | |
31 | */ | |
6a5fa598 | 32 | #define rseq_after_asm_goto() __asm__ __volatile__ ("" : : : "memory") |
dd76f2d6 | 33 | |
eb5d1cbe MD |
34 | #if defined(__SIZEOF_LONG__) |
35 | #define RSEQ_BITS_PER_LONG (__SIZEOF_LONG__ * 8) | |
36 | #elif defined(_LP64) | |
37 | #define RSEQ_BITS_PER_LONG 64 | |
38 | #else | |
39 | #define RSEQ_BITS_PER_LONG 32 | |
40 | #endif | |
41 | ||
d292e9e1 MD |
42 | #ifdef __cplusplus |
43 | #define rseq_unqual_scalar_typeof(x) \ | |
732b2f65 | 44 | __typeof__(reinterpret_cast<std::remove_cv<__typeof__(x)>::type>((__typeof__(x))0)) |
d292e9e1 MD |
45 | #else |
46 | /* | |
47 | * Use C11 _Generic to express unqualified type from expression. This removes | |
48 | * volatile qualifier from expression type. | |
49 | */ | |
50 | #define rseq_unqual_scalar_typeof(x) \ | |
51 | __typeof__( \ | |
52 | _Generic((x), \ | |
53 | char: (char)0, \ | |
54 | unsigned char: (unsigned char)0, \ | |
55 | signed char: (signed char)0, \ | |
56 | unsigned short: (unsigned short)0, \ | |
57 | signed short: (signed short)0, \ | |
58 | unsigned int: (unsigned int)0, \ | |
59 | signed int: (signed int)0, \ | |
60 | unsigned long: (unsigned long)0, \ | |
61 | signed long: (signed long)0, \ | |
62 | unsigned long long: (unsigned long long)0, \ | |
63 | signed long long: (signed long long)0, \ | |
64 | default: (x) \ | |
65 | ) \ | |
66 | ) | |
67 | #endif | |
68 | ||
dd76f2d6 | 69 | #endif /* RSEQ_COMPILER_H_ */ |