Home | History | Annotate | Download | only in pipe
      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
     65 extern "C" {
     66 #endif
     67 
     68 
     69 #if !defined(__HAIKU__) && !defined(__USE_MISC)
     70 #if !defined(PIPE_OS_ANDROID)
     71 typedef unsigned int       uint;
     72 #endif
     73 typedef unsigned short     ushort;
     74 #endif
     75 typedef unsigned char      ubyte;
     76 
     77 typedef 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 
    256 void _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