1/************************************************************************** 2 * 3 * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 "p_config.h" 33 34#include <stdlib.h> 35#include <string.h> 36#include <stddef.h> 37#include <stdarg.h> 38#include <limits.h> 39 40 41#if defined(_WIN32) && !defined(__WIN32__) 42#define __WIN32__ 43#endif 44 45#if defined(_MSC_VER) 46 47/* Avoid 'expression is always true' warning */ 48#pragma warning(disable: 4296) 49 50#endif /* _MSC_VER */ 51 52 53/* 54 * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for 55 * systems that lack it. 56 */ 57#ifndef __STDC_LIMIT_MACROS 58#define __STDC_LIMIT_MACROS 1 59#endif 60#include <stdint.h> 61#include <stdbool.h> 62 63 64#ifdef __cplusplus 65extern "C" { 66#endif 67 68 69#if !defined(__HAIKU__) && !defined(__USE_MISC) 70#if !defined(PIPE_OS_ANDROID) 71typedef unsigned int uint; 72#endif 73typedef unsigned short ushort; 74#endif 75typedef unsigned char ubyte; 76 77typedef unsigned char boolean; 78#ifndef TRUE 79#define TRUE true 80#endif 81#ifndef FALSE 82#define FALSE false 83#endif 84 85#ifndef va_copy 86#ifdef __va_copy 87#define va_copy(dest, src) __va_copy((dest), (src)) 88#else 89#define va_copy(dest, src) (dest) = (src) 90#endif 91#endif 92 93/* Function inlining */ 94#ifndef inline 95# ifdef __cplusplus 96 /* C++ supports inline keyword */ 97# elif defined(__GNUC__) 98# define inline __inline__ 99# elif defined(_MSC_VER) 100# define inline __inline 101# elif defined(__ICL) 102# define inline __inline 103# elif defined(__INTEL_COMPILER) 104 /* Intel compiler supports inline keyword */ 105# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) 106# define inline __inline 107# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) 108 /* C99 supports inline keyword */ 109# elif (__STDC_VERSION__ >= 199901L) 110 /* C99 supports inline keyword */ 111# else 112# define inline 113# endif 114#endif 115#ifndef INLINE 116# define INLINE inline 117#endif 118 119/* Forced function inlining */ 120#ifndef ALWAYS_INLINE 121# ifdef __GNUC__ 122# define ALWAYS_INLINE inline __attribute__((always_inline)) 123# elif defined(_MSC_VER) 124# define ALWAYS_INLINE __forceinline 125# else 126# define ALWAYS_INLINE INLINE 127# endif 128#endif 129 130/* 131 * Define the C99 restrict keyword. 132 * 133 * See also: 134 * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html 135 */ 136#ifndef restrict 137# if (__STDC_VERSION__ >= 199901L) 138 /* C99 */ 139# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) 140 /* C99 */ 141# elif defined(__GNUC__) 142# define restrict __restrict__ 143# elif defined(_MSC_VER) 144# define restrict __restrict 145# else 146# define restrict /* */ 147# endif 148#endif 149 150 151/* Function visibility */ 152#ifndef PUBLIC 153# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 154# define PUBLIC __attribute__((visibility("default"))) 155# elif defined(_MSC_VER) 156# define PUBLIC __declspec(dllexport) 157# else 158# define PUBLIC 159# endif 160#endif 161 162 163/* The __FUNCTION__ gcc variable is generally only used for debugging. 164 * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. 165 */ 166#ifndef __FUNCTION__ 167# if !defined(__GNUC__) 168# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ 169 (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 170# define __FUNCTION__ __func__ 171# else 172# define __FUNCTION__ "<unknown>" 173# endif 174# endif 175# if defined(_MSC_VER) && _MSC_VER < 1300 176# define __FUNCTION__ "<unknown>" 177# endif 178#endif 179#ifndef __func__ 180# if (__STDC_VERSION__ >= 199901L) || \ 181 (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 182 /* __func__ is part of C99 */ 183# elif defined(_MSC_VER) 184# if _MSC_VER >= 1300 185# define __func__ __FUNCTION__ 186# else 187# define __func__ "<unknown>" 188# endif 189# endif 190#endif 191 192 193 194/* This should match linux gcc cdecl semantics everywhere, so that we 195 * just codegen one calling convention on all platforms. 196 */ 197#ifdef _MSC_VER 198#define PIPE_CDECL __cdecl 199#else 200#define PIPE_CDECL 201#endif 202 203 204 205#if defined(__GNUC__) 206#define PIPE_DEPRECATED __attribute__((__deprecated__)) 207#else 208#define PIPE_DEPRECATED 209#endif 210 211 212 213/* Macros for data alignment. */ 214#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) || defined(__SUNPRO_CC) 215 216/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */ 217#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment))) 218 219/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */ 220#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment))) 221 222#if (__GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)) && !defined(PIPE_ARCH_X86_64) 223#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer)) 224#else 225#define PIPE_ALIGN_STACK 226#endif 227 228#elif defined(_MSC_VER) 229 230/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */ 231#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type 232#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment)) 233 234#define PIPE_ALIGN_STACK 235 236#elif defined(SWIG) 237 238#define PIPE_ALIGN_TYPE(_alignment, _type) _type 239#define PIPE_ALIGN_VAR(_alignment) 240 241#define PIPE_ALIGN_STACK 242 243#else 244 245#error "Unsupported compiler" 246 247#endif 248 249 250#if defined(__GNUC__) 251 252#define PIPE_READ_WRITE_BARRIER() __asm__("":::"memory") 253 254#elif defined(_MSC_VER) 255 256void _ReadWriteBarrier(void); 257#pragma intrinsic(_ReadWriteBarrier) 258#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier() 259 260#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 261 262#define PIPE_READ_WRITE_BARRIER() __machine_rw_barrier() 263 264#else 265 266#warning "Unsupported compiler" 267#define PIPE_READ_WRITE_BARRIER() /* */ 268 269#endif 270 271 272/* You should use these macros to mark if blocks where the if condition 273 * is either likely to be true, or unlikely to be true. 274 * 275 * This will inform human readers of this fact, and will also inform 276 * the compiler, who will in turn inform the CPU. 277 * 278 * CPUs often start executing code inside the if or the else blocks 279 * without knowing whether the condition is true or not, and will have 280 * to throw the work away if they find out later they executed the 281 * wrong part of the if. 282 * 283 * If these macros are used, the CPU is more likely to correctly predict 284 * the right path, and will avoid speculatively executing the wrong branch, 285 * thus not throwing away work, resulting in better performance. 286 * 287 * In light of this, it is also a good idea to mark as "likely" a path 288 * which is not necessarily always more likely, but that will benefit much 289 * more from performance improvements since it is already much faster than 290 * the other path, or viceversa with "unlikely". 291 * 292 * Example usage: 293 * if(unlikely(do_we_need_a_software_fallback())) 294 * do_software_fallback(); 295 * else 296 * render_with_gpu(); 297 * 298 * The macros follow the Linux kernel convention, and more examples can 299 * be found there. 300 * 301 * Note that profile guided optimization can offer better results, but 302 * needs an appropriate coverage suite and does not inform human readers. 303 */ 304#ifndef likely 305# if defined(__GNUC__) 306# define likely(x) __builtin_expect(!!(x), 1) 307# define unlikely(x) __builtin_expect(!!(x), 0) 308# else 309# define likely(x) (x) 310# define unlikely(x) (x) 311# endif 312#endif 313 314 315/** 316 * Static (compile-time) assertion. 317 * Basically, use COND to dimension an array. If COND is false/zero the 318 * array size will be -1 and we'll get a compilation error. 319 */ 320#define STATIC_ASSERT(COND) \ 321 do { \ 322 typedef int static_assertion_failed[(!!(COND))*2-1]; \ 323 } while (0) 324 325 326#if defined(__cplusplus) 327} 328#endif 329 330 331#endif /* P_COMPILER_H */ 332