1b53823fbSMathieu Desnoyers /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 2b53823fbSMathieu Desnoyers /* 3b53823fbSMathieu Desnoyers * rseq/compiler.h 4b53823fbSMathieu Desnoyers * 5b53823fbSMathieu Desnoyers * Work-around asm goto compiler bugs. 6b53823fbSMathieu Desnoyers * 7b53823fbSMathieu Desnoyers * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 8b53823fbSMathieu Desnoyers */ 9b53823fbSMathieu Desnoyers 10b53823fbSMathieu Desnoyers #ifndef RSEQ_COMPILER_H 11b53823fbSMathieu Desnoyers #define RSEQ_COMPILER_H 12b53823fbSMathieu Desnoyers 13b53823fbSMathieu Desnoyers /* 14b53823fbSMathieu Desnoyers * gcc prior to 4.8.2 miscompiles asm goto. 15b53823fbSMathieu Desnoyers * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 16b53823fbSMathieu Desnoyers * 17b53823fbSMathieu Desnoyers * gcc prior to 8.1.0 miscompiles asm goto at O1. 18b53823fbSMathieu Desnoyers * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908 19b53823fbSMathieu Desnoyers * 20b53823fbSMathieu Desnoyers * clang prior to version 13.0.1 miscompiles asm goto at O2. 21b53823fbSMathieu Desnoyers * https://github.com/llvm/llvm-project/issues/52735 22b53823fbSMathieu Desnoyers * 23b53823fbSMathieu Desnoyers * Work around these issues by adding a volatile inline asm with 24b53823fbSMathieu Desnoyers * memory clobber in the fallthrough after the asm goto and at each 25b53823fbSMathieu Desnoyers * label target. Emit this for all compilers in case other similar 26b53823fbSMathieu Desnoyers * issues are found in the future. 27b53823fbSMathieu Desnoyers */ 28b53823fbSMathieu Desnoyers #define rseq_after_asm_goto() asm volatile ("" : : : "memory") 29b53823fbSMathieu Desnoyers 30ae315738SMathieu Desnoyers /* Combine two tokens. */ 31ae315738SMathieu Desnoyers #define RSEQ__COMBINE_TOKENS(_tokena, _tokenb) \ 32ae315738SMathieu Desnoyers _tokena##_tokenb 33ae315738SMathieu Desnoyers #define RSEQ_COMBINE_TOKENS(_tokena, _tokenb) \ 34ae315738SMathieu Desnoyers RSEQ__COMBINE_TOKENS(_tokena, _tokenb) 35ae315738SMathieu Desnoyers 36*d6aaa23aSMathieu Desnoyers #ifdef __cplusplus 37*d6aaa23aSMathieu Desnoyers #define rseq_unqual_scalar_typeof(x) \ 38*d6aaa23aSMathieu Desnoyers std::remove_cv<std::remove_reference<decltype(x)>::type>::type 39*d6aaa23aSMathieu Desnoyers #else 40*d6aaa23aSMathieu Desnoyers #define rseq_scalar_type_to_expr(type) \ 41*d6aaa23aSMathieu Desnoyers unsigned type: (unsigned type)0, \ 42*d6aaa23aSMathieu Desnoyers signed type: (signed type)0 43*d6aaa23aSMathieu Desnoyers 44*d6aaa23aSMathieu Desnoyers /* 45*d6aaa23aSMathieu Desnoyers * Use C11 _Generic to express unqualified type from expression. This removes 46*d6aaa23aSMathieu Desnoyers * volatile qualifier from expression type. 47*d6aaa23aSMathieu Desnoyers */ 48*d6aaa23aSMathieu Desnoyers #define rseq_unqual_scalar_typeof(x) \ 49*d6aaa23aSMathieu Desnoyers __typeof__( \ 50*d6aaa23aSMathieu Desnoyers _Generic((x), \ 51*d6aaa23aSMathieu Desnoyers char: (char)0, \ 52*d6aaa23aSMathieu Desnoyers rseq_scalar_type_to_expr(char), \ 53*d6aaa23aSMathieu Desnoyers rseq_scalar_type_to_expr(short), \ 54*d6aaa23aSMathieu Desnoyers rseq_scalar_type_to_expr(int), \ 55*d6aaa23aSMathieu Desnoyers rseq_scalar_type_to_expr(long), \ 56*d6aaa23aSMathieu Desnoyers rseq_scalar_type_to_expr(long long), \ 57*d6aaa23aSMathieu Desnoyers default: (x) \ 58*d6aaa23aSMathieu Desnoyers ) \ 59*d6aaa23aSMathieu Desnoyers ) 60*d6aaa23aSMathieu Desnoyers #endif 61*d6aaa23aSMathieu Desnoyers 62b53823fbSMathieu Desnoyers #endif /* RSEQ_COMPILER_H_ */ 63