1// Copyright 2015 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef HIGHWAYHASH_COMPILER_SPECIFIC_H_
16#define HIGHWAYHASH_COMPILER_SPECIFIC_H_
17
18// WARNING: this is a "restricted" header because it is included from
19// translation units compiled with different flags. This header and its
20// dependencies must not define any function unless it is static inline and/or
21// within namespace HH_TARGET_NAME. See arch_specific.h for details.
22
23// Compiler
24
25// #if is shorter and safer than #ifdef. *_VERSION are zero if not detected,
26// otherwise 100 * major + minor version. Note that other packages check for
27// #ifdef COMPILER_MSVC, so we cannot use that same name.
28
29#ifdef _MSC_VER
30#define HH_MSC_VERSION _MSC_VER
31#else
32#define HH_MSC_VERSION 0
33#endif
34
35#ifdef __GNUC__
36#define HH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
37#else
38#define HH_GCC_VERSION 0
39#endif
40
41#ifdef __clang__
42#define HH_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
43#else
44#define HH_CLANG_VERSION 0
45#endif
46
47//-----------------------------------------------------------------------------
48
49#if HH_GCC_VERSION && HH_GCC_VERSION < 408
50#define HH_ALIGNAS(multiple) __attribute__((aligned(multiple)))
51#else
52#define HH_ALIGNAS(multiple) alignas(multiple) // C++11
53#endif
54
55#if HH_MSC_VERSION
56#define HH_RESTRICT __restrict
57#elif HH_GCC_VERSION
58#define HH_RESTRICT __restrict__
59#else
60#define HH_RESTRICT
61#endif
62
63#if HH_MSC_VERSION
64#define HH_INLINE __forceinline
65#define HH_NOINLINE __declspec(noinline)
66#else
67#define HH_INLINE inline
68#define HH_NOINLINE __attribute__((noinline))
69#endif
70
71#if HH_MSC_VERSION
72// Unsupported, __assume is not the same.
73#define HH_LIKELY(expr) expr
74#define HH_UNLIKELY(expr) expr
75#else
76#define HH_LIKELY(expr) __builtin_expect(!!(expr), 1)
77#define HH_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
78#endif
79
80#if HH_MSC_VERSION
81#include <intrin.h>
82#pragma intrinsic(_ReadWriteBarrier)
83#define HH_COMPILER_FENCE _ReadWriteBarrier()
84#elif HH_GCC_VERSION
85#define HH_COMPILER_FENCE asm volatile("" : : : "memory")
86#else
87#define HH_COMPILER_FENCE
88#endif
89
90#endif // HIGHWAYHASH_COMPILER_SPECIFIC_H_
91