p_compiler.h revision 848b8605
1/************************************************************************** 2 * 3 * Copyright 2007-2008 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#ifndef P_COMPILER_H 29#define P_COMPILER_H 30 31 32#include "c99_compat.h" /* inline, __func__, etc. */ 33 34#include "p_config.h" 35 36#include <stdlib.h> 37#include <string.h> 38#include <stddef.h> 39#include <stdarg.h> 40#include <limits.h> 41 42 43#if defined(_WIN32) && !defined(__WIN32__) 44#define __WIN32__ 45#endif 46 47#if defined(_MSC_VER) 48 49/* Avoid 'expression is always true' warning */ 50#pragma warning(disable: 4296) 51 52#endif /* _MSC_VER */ 53 54 55/* 56 * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for 57 * systems that lack it. 58 */ 59#ifndef __STDC_LIMIT_MACROS 60#define __STDC_LIMIT_MACROS 1 61#endif 62#include <stdint.h> 63#include <stdbool.h> 64 65 66#ifdef __cplusplus 67extern "C" { 68#endif 69 70 71#if !defined(__HAIKU__) && !defined(__USE_MISC) 72#if !defined(PIPE_OS_ANDROID) 73typedef unsigned int uint; 74#endif 75typedef unsigned short ushort; 76#endif 77typedef unsigned char ubyte; 78 79typedef unsigned char boolean; 80#ifndef TRUE 81#define TRUE true 82#endif 83#ifndef FALSE 84#define FALSE false 85#endif 86 87#ifndef va_copy 88#ifdef __va_copy 89#define va_copy(dest, src) __va_copy((dest), (src)) 90#else 91#define va_copy(dest, src) (dest) = (src) 92#endif 93#endif 94 95/* XXX: Use standard `inline` keyword instead */ 96#ifndef INLINE 97# define INLINE inline 98#endif 99 100/* Forced function inlining */ 101#ifndef ALWAYS_INLINE 102# ifdef __GNUC__ 103# define ALWAYS_INLINE inline __attribute__((always_inline)) 104# elif defined(_MSC_VER) 105# define ALWAYS_INLINE __forceinline 106# else 107# define ALWAYS_INLINE INLINE 108# endif 109#endif 110 111 112/* Function visibility */ 113#ifndef PUBLIC 114# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 115# define PUBLIC __attribute__((visibility("default"))) 116# elif defined(_MSC_VER) 117# define PUBLIC __declspec(dllexport) 118# else 119# define PUBLIC 120# endif 121#endif 122 123 124/* XXX: Use standard `__func__` instead */ 125#ifndef __FUNCTION__ 126# define __FUNCTION__ __func__ 127#endif 128 129 130/* This should match linux gcc cdecl semantics everywhere, so that we 131 * just codegen one calling convention on all platforms. 132 */ 133#ifdef _MSC_VER 134#define PIPE_CDECL __cdecl 135#else 136#define PIPE_CDECL 137#endif 138 139 140 141#if defined(__GNUC__) 142#define PIPE_DEPRECATED __attribute__((__deprecated__)) 143#else 144#define PIPE_DEPRECATED 145#endif 146 147 148 149/* Macros for data alignment. */ 150#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) || defined(__SUNPRO_CC) 151 152/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */ 153#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment))) 154 155/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */ 156#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment))) 157 158#if (__GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)) && !defined(PIPE_ARCH_X86_64) 159#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer)) 160#else 161#define PIPE_ALIGN_STACK 162#endif 163 164#elif defined(_MSC_VER) 165 166/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */ 167#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type 168#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment)) 169 170#define PIPE_ALIGN_STACK 171 172#elif defined(SWIG) 173 174#define PIPE_ALIGN_TYPE(_alignment, _type) _type 175#define PIPE_ALIGN_VAR(_alignment) 176 177#define PIPE_ALIGN_STACK 178 179#else 180 181#error "Unsupported compiler" 182 183#endif 184 185 186#if defined(__GNUC__) 187 188#define PIPE_READ_WRITE_BARRIER() __asm__("":::"memory") 189 190#elif defined(_MSC_VER) 191 192void _ReadWriteBarrier(void); 193#pragma intrinsic(_ReadWriteBarrier) 194#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier() 195 196#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 197 198#define PIPE_READ_WRITE_BARRIER() __machine_rw_barrier() 199 200#else 201 202#warning "Unsupported compiler" 203#define PIPE_READ_WRITE_BARRIER() /* */ 204 205#endif 206 207 208/* You should use these macros to mark if blocks where the if condition 209 * is either likely to be true, or unlikely to be true. 210 * 211 * This will inform human readers of this fact, and will also inform 212 * the compiler, who will in turn inform the CPU. 213 * 214 * CPUs often start executing code inside the if or the else blocks 215 * without knowing whether the condition is true or not, and will have 216 * to throw the work away if they find out later they executed the 217 * wrong part of the if. 218 * 219 * If these macros are used, the CPU is more likely to correctly predict 220 * the right path, and will avoid speculatively executing the wrong branch, 221 * thus not throwing away work, resulting in better performance. 222 * 223 * In light of this, it is also a good idea to mark as "likely" a path 224 * which is not necessarily always more likely, but that will benefit much 225 * more from performance improvements since it is already much faster than 226 * the other path, or viceversa with "unlikely". 227 * 228 * Example usage: 229 * if(unlikely(do_we_need_a_software_fallback())) 230 * do_software_fallback(); 231 * else 232 * render_with_gpu(); 233 * 234 * The macros follow the Linux kernel convention, and more examples can 235 * be found there. 236 * 237 * Note that profile guided optimization can offer better results, but 238 * needs an appropriate coverage suite and does not inform human readers. 239 */ 240#ifndef likely 241# if defined(__GNUC__) 242# define likely(x) __builtin_expect(!!(x), 1) 243# define unlikely(x) __builtin_expect(!!(x), 0) 244# else 245# define likely(x) (x) 246# define unlikely(x) (x) 247# endif 248#endif 249 250 251/** 252 * Static (compile-time) assertion. 253 * Basically, use COND to dimension an array. If COND is false/zero the 254 * array size will be -1 and we'll get a compilation error. 255 */ 256#define STATIC_ASSERT(COND) \ 257 do { \ 258 (void) sizeof(char [1 - 2*!(COND)]); \ 259 } while (0) 260 261 262#if defined(__cplusplus) 263} 264#endif 265 266 267#endif /* P_COMPILER_H */ 268