1/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
2/*
3 * Copyright (c) Meta Platforms, Inc. and affiliates.
4 * All rights reserved.
5 *
6 * This source code is licensed under both the BSD-style license (found in the
7 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
8 * in the COPYING file in the root directory of this source tree).
9 * You may select, at your option, one of the above-listed licenses.
10 */
11
12#ifndef ZSTD_PORTABILITY_MACROS_H
13#define ZSTD_PORTABILITY_MACROS_H
14
15/*
16 * This header file contains macro definitions to support portability.
17 * This header is shared between C and ASM code, so it MUST only
18 * contain macro definitions. It MUST not contain any C code.
19 *
20 * This header ONLY defines macros to detect platforms/feature support.
21 *
22 */
23
24
25/* compat. with non-clang compilers */
26#ifndef __has_attribute
27 #define __has_attribute(x) 0
28#endif
29
30/* compat. with non-clang compilers */
31#ifndef __has_builtin
32# define __has_builtin(x) 0
33#endif
34
35/* compat. with non-clang compilers */
36#ifndef __has_feature
37# define __has_feature(x) 0
38#endif
39
40/* detects whether we are being compiled under msan */
41
42/* detects whether we are being compiled under asan */
43
44/* detects whether we are being compiled under dfsan */
45
46/* Mark the internal assembly functions as hidden */
47#ifdef __ELF__
48# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
49#elif defined(__APPLE__)
50# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func
51#else
52# define ZSTD_HIDE_ASM_FUNCTION(func)
53#endif
54
55/* Compile time determination of BMI2 support */
56
57
58/* Enable runtime BMI2 dispatch based on the CPU.
59 * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
60 */
61#ifndef DYNAMIC_BMI2
62# if ((defined(__clang__) && __has_attribute(__target__)) \
63 || (defined(__GNUC__) \
64 && (__GNUC__ >= 11))) \
65 && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \
66 && !defined(__BMI2__)
67# define DYNAMIC_BMI2 1
68# else
69# define DYNAMIC_BMI2 0
70# endif
71#endif
72
73/*
74 * Only enable assembly for GNU C compatible compilers,
75 * because other platforms may not support GAS assembly syntax.
76 *
77 * Only enable assembly for Linux / MacOS / Win32, other platforms may
78 * work, but they haven't been tested. This could likely be
79 * extended to BSD systems.
80 *
81 * Disable assembly when MSAN is enabled, because MSAN requires
82 * 100% of code to be instrumented to work.
83 */
84#define ZSTD_ASM_SUPPORTED 1
85
86/*
87 * Determines whether we should enable assembly for x86-64
88 * with BMI2.
89 *
90 * Enable if all of the following conditions hold:
91 * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM
92 * - Assembly is supported
93 * - We are compiling for x86-64 and either:
94 * - DYNAMIC_BMI2 is enabled
95 * - BMI2 is supported at compile time
96 */
97#define ZSTD_ENABLE_ASM_X86_64_BMI2 0
98
99/*
100 * For x86 ELF targets, add .note.gnu.property section for Intel CET in
101 * assembly sources when CET is enabled.
102 *
103 * Additionally, any function that may be called indirectly must begin
104 * with ZSTD_CET_ENDBRANCH.
105 */
106#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \
107 && defined(__has_include)
108# if __has_include(<cet.h>)
109# include <cet.h>
110# define ZSTD_CET_ENDBRANCH _CET_ENDBR
111# endif
112#endif
113
114#ifndef ZSTD_CET_ENDBRANCH
115# define ZSTD_CET_ENDBRANCH
116#endif
117
118#endif /* ZSTD_PORTABILITY_MACROS_H */
119