p_compiler.h revision ba26631d0d936523c7a8f002cf469e569aa6d7a3
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 39 40#if defined(_WIN32) && !defined(__WIN32__) 41#define __WIN32__ 42#endif 43 44#if defined(_MSC_VER) 45 46/* Avoid 'expression is always true' warning */ 47#pragma warning(disable: 4296) 48 49#endif /* _MSC_VER */ 50 51 52/* 53 * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for 54 * systems that lack it. 55 */ 56#ifndef __STDC_LIMIT_MACROS 57#define __STDC_LIMIT_MACROS 1 58#endif 59#include <stdint.h> 60#include <stdbool.h> 61 62 63#if !defined(__HAIKU__) && !defined(__USE_MISC) 64typedef unsigned int uint; 65typedef unsigned short ushort; 66#endif 67typedef unsigned char ubyte; 68 69typedef unsigned char boolean; 70#ifndef TRUE 71#define TRUE true 72#endif 73#ifndef FALSE 74#define FALSE false 75#endif 76 77/* Function inlining */ 78#ifndef INLINE 79# ifdef __cplusplus 80# define INLINE inline 81# elif defined(__GNUC__) 82# define INLINE __inline__ 83# elif defined(_MSC_VER) 84# define INLINE __inline 85# elif defined(__ICL) 86# define INLINE __inline 87# elif defined(__INTEL_COMPILER) 88# define INLINE inline 89# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) 90# define INLINE __inline 91# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) 92# define INLINE inline 93# elif (__STDC_VERSION__ >= 199901L) /* C99 */ 94# define INLINE inline 95# else 96# define INLINE 97# endif 98#endif 99 100 101/* Function visibility */ 102#ifndef PUBLIC 103# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 104# define PUBLIC __attribute__((visibility("default"))) 105# elif defined(_MSC_VER) 106# define PUBLIC __declspec(dllexport) 107# else 108# define PUBLIC 109# endif 110#endif 111 112 113/* The __FUNCTION__ gcc variable is generally only used for debugging. 114 * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. 115 */ 116#ifndef __FUNCTION__ 117# if !defined(__GNUC__) 118# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ 119 (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 120# define __FUNCTION__ __func__ 121# else 122# define __FUNCTION__ "<unknown>" 123# endif 124# endif 125# if defined(_MSC_VER) && _MSC_VER < 1300 126# define __FUNCTION__ "<unknown>" 127# endif 128#endif 129 130 131 132/* This should match linux gcc cdecl semantics everywhere, so that we 133 * just codegen one calling convention on all platforms. 134 */ 135#ifdef _MSC_VER 136#define PIPE_CDECL __cdecl 137#else 138#define PIPE_CDECL 139#endif 140 141 142 143#if defined(__GNUC__) 144#define PIPE_DEPRECATED __attribute__((__deprecated__)) 145#else 146#define PIPE_DEPRECATED 147#endif 148 149 150 151/* Macros for data alignment. */ 152#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 153 154/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */ 155#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment))) 156 157/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */ 158#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment))) 159 160#if (__GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)) && !defined(PIPE_ARCH_X86_64) 161#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer)) 162#else 163#define PIPE_ALIGN_STACK 164#endif 165 166#elif defined(_MSC_VER) 167 168/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */ 169#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type 170#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment)) 171 172#define PIPE_ALIGN_STACK 173 174#elif defined(SWIG) 175 176#define PIPE_ALIGN_TYPE(_alignment, _type) _type 177#define PIPE_ALIGN_VAR(_alignment) 178 179#define PIPE_ALIGN_STACK 180 181#else 182 183#error "Unsupported compiler" 184 185#endif 186 187/* You should use these macros to mark if blocks where the if condition 188 * is either likely to be true, or unlikely to be true. 189 * 190 * This will inform human readers of this fact, and will also inform 191 * the compiler, who will in turn inform the CPU. 192 * 193 * CPUs often start executing code inside the if or the else blocks 194 * without knowing whether the condition is true or not, and will have 195 * to throw the work away if they find out later they executed the 196 * wrong part of the if. 197 * 198 * If these macros are used, the CPU is more likely to correctly predict 199 * the right path, and will avoid speculatively executing the wrong branch, 200 * thus not throwing away work, resulting in better performance. 201 * 202 * In light of this, it is also a good idea to mark as "likely" a path 203 * which is not necessarily always more likely, but that will benefit much 204 * more from performance improvements since it is already much faster than 205 * the other path, or viceversa with "unlikely". 206 * 207 * Example usage: 208 * if(unlikely(do_we_need_a_software_fallback())) 209 * do_software_fallback(); 210 * else 211 * render_with_gpu(); 212 * 213 * The macros follow the Linux kernel convention, and more examples can 214 * be found there. 215 * 216 * Note that profile guided optimization can offer better results, but 217 * needs an appropriate coverage suite and does not inform human readers. 218 */ 219#ifdef __GNUC__ 220#define likely(x) __builtin_expect(!!(x), 1) 221#define unlikely(x) __builtin_expect(!!(x), 0) 222#else 223#define likely(x) !!(x) 224#define unlikely(x) !!(x) 225#endif 226 227#endif /* P_COMPILER_H */ 228