162306a36Sopenharmony_ci/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * rseq/compiler.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Work-around asm goto compiler bugs. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef RSEQ_COMPILER_H 1162306a36Sopenharmony_ci#define RSEQ_COMPILER_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * gcc prior to 4.8.2 miscompiles asm goto. 1562306a36Sopenharmony_ci * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * gcc prior to 8.1.0 miscompiles asm goto at O1. 1862306a36Sopenharmony_ci * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * clang prior to version 13.0.1 miscompiles asm goto at O2. 2162306a36Sopenharmony_ci * https://github.com/llvm/llvm-project/issues/52735 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * Work around these issues by adding a volatile inline asm with 2462306a36Sopenharmony_ci * memory clobber in the fallthrough after the asm goto and at each 2562306a36Sopenharmony_ci * label target. Emit this for all compilers in case other similar 2662306a36Sopenharmony_ci * issues are found in the future. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci#define rseq_after_asm_goto() asm volatile ("" : : : "memory") 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* Combine two tokens. */ 3162306a36Sopenharmony_ci#define RSEQ__COMBINE_TOKENS(_tokena, _tokenb) \ 3262306a36Sopenharmony_ci _tokena##_tokenb 3362306a36Sopenharmony_ci#define RSEQ_COMBINE_TOKENS(_tokena, _tokenb) \ 3462306a36Sopenharmony_ci RSEQ__COMBINE_TOKENS(_tokena, _tokenb) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#ifdef __cplusplus 3762306a36Sopenharmony_ci#define rseq_unqual_scalar_typeof(x) \ 3862306a36Sopenharmony_ci std::remove_cv<std::remove_reference<decltype(x)>::type>::type 3962306a36Sopenharmony_ci#else 4062306a36Sopenharmony_ci#define rseq_scalar_type_to_expr(type) \ 4162306a36Sopenharmony_ci unsigned type: (unsigned type)0, \ 4262306a36Sopenharmony_ci signed type: (signed type)0 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * Use C11 _Generic to express unqualified type from expression. This removes 4662306a36Sopenharmony_ci * volatile qualifier from expression type. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#define rseq_unqual_scalar_typeof(x) \ 4962306a36Sopenharmony_ci __typeof__( \ 5062306a36Sopenharmony_ci _Generic((x), \ 5162306a36Sopenharmony_ci char: (char)0, \ 5262306a36Sopenharmony_ci rseq_scalar_type_to_expr(char), \ 5362306a36Sopenharmony_ci rseq_scalar_type_to_expr(short), \ 5462306a36Sopenharmony_ci rseq_scalar_type_to_expr(int), \ 5562306a36Sopenharmony_ci rseq_scalar_type_to_expr(long), \ 5662306a36Sopenharmony_ci rseq_scalar_type_to_expr(long long), \ 5762306a36Sopenharmony_ci default: (x) \ 5862306a36Sopenharmony_ci ) \ 5962306a36Sopenharmony_ci ) 6062306a36Sopenharmony_ci#endif 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#endif /* RSEQ_COMPILER_H_ */ 63