port.h revision db71549ac5008174ed4ada46476f0a74144bf2fc
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 16/* Macros for branch prediction. */ 17 18#ifndef BROTLI_DEC_PORT_H_ 19#define BROTLI_DEC_PORT_H_ 20 21#include<assert.h> 22 23/* Compatibility with non-clang compilers. */ 24#ifndef __has_builtin 25#define __has_builtin(x) 0 26#endif 27 28#ifndef __has_attribute 29#define __has_attribute(x) 0 30#endif 31 32#ifndef __has_feature 33#define __has_feature(x) 0 34#endif 35 36#define BROTLI_ASAN_BUILD __has_feature(address_sanitizer) 37 38/* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers. 39 40To apply compiler hint, enclose the branching condition into macros, like this: 41 42 if (PREDICT_TRUE(zero == 0)) { 43 // main execution path 44 } else { 45 // compiler should place this code outside of main execution path 46 } 47 48OR: 49 50 if (PREDICT_FALSE(something_rare_or_unexpected_happens)) { 51 // compiler should place this code outside of main execution path 52 } 53 54*/ 55#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || \ 56 (defined(__llvm__) && __has_builtin(__builtin_expect)) 57#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) 58#define PREDICT_FALSE(x) (__builtin_expect(x, 0)) 59#else 60#define PREDICT_FALSE(x) (x) 61#define PREDICT_TRUE(x) (x) 62#endif 63 64/* IS_CONSTANT macros returns true for compile-time constant expressions. */ 65#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) || \ 66 (defined(__llvm__) && __has_builtin(__builtin_constant_p)) 67#define IS_CONSTANT(x) __builtin_constant_p(x) 68#else 69#define IS_CONSTANT(x) 0 70#endif 71 72#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) || \ 73 (defined(__llvm__) && __has_attribute(always_inline)) 74#define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) 75#else 76#define ATTRIBUTE_ALWAYS_INLINE 77#endif 78 79#ifndef _MSC_VER 80#if defined(__cplusplus) || !defined(__STRICT_ANSI__) \ 81 || __STDC_VERSION__ >= 199901L 82#define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE 83#else 84#define BROTLI_INLINE 85#endif 86#else /* _MSC_VER */ 87#define BROTLI_INLINE __forceinline 88#endif /* _MSC_VER */ 89 90#ifdef BROTLI_DECODE_DEBUG 91#define BROTLI_DCHECK(x) assert(x) 92#else 93#define BROTLI_DCHECK(x) 94#endif 95 96#if (defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || \ 97 defined(__PPC64__)) 98#define BROTLI_64_BITS 1 99#define BROTLI_PRELOAD_SYMBOLS 1 100#else 101#define BROTLI_64_BITS 0 102#define BROTLI_PRELOAD_SYMBOLS 0 103#endif 104 105#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) 106#define BROTLI_LITTLE_ENDIAN 1 107#elif defined(_WIN32) 108/* Win32 can currently always be assumed to be little endian */ 109#define BROTLI_LITTLE_ENDIAN 1 110#else 111#define BROTLI_LITTLE_ENDIAN 0 112#endif 113 114#if (BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN) 115#define BROTLI_64_BITS_LITTLE_ENDIAN 1 116#else 117#define BROTLI_64_BITS_LITTLE_ENDIAN 0 118#endif 119 120#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || \ 121 (defined(__llvm__) && __has_attribute(noinline)) 122#define BROTLI_NOINLINE __attribute__ ((noinline)) 123#else 124#define BROTLI_NOINLINE 125#endif 126 127#if BROTLI_ASAN_BUILD 128#define BROTLI_NO_ASAN __attribute__((no_sanitize("address"))) BROTLI_NOINLINE 129#else 130#define BROTLI_NO_ASAN 131#endif 132 133#define BROTLI_REPEAT(N, X) { \ 134 if ((N & 1) != 0) {X;} \ 135 if ((N & 2) != 0) {X; X;} \ 136 if ((N & 4) != 0) {X; X; X; X;} \ 137} 138 139#if (__GNUC__ > 2) || defined(__llvm__) 140#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) 141static BROTLI_INLINE unsigned BrotliRBit(unsigned input) { 142 unsigned output; 143 __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); 144 return output; 145} 146#define BROTLI_RBIT(x) BrotliRBit(x) 147#endif /* armv7 */ 148#endif /* gcc || clang */ 149 150#endif /* BROTLI_DEC_PORT_H_ */ 151