compiler.h revision f2c023291a1f2887294d2aac504f8b82857ad092
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions 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 MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/** 28 * \file compiler.h 29 * Compiler-related stuff. 30 */ 31 32 33#ifndef COMPILER_H 34#define COMPILER_H 35 36 37#include <assert.h> 38#include <ctype.h> 39#if defined(__alpha__) && defined(CCPML) 40#include <cpml.h> /* use Compaq's Fast Math Library on Alpha */ 41#else 42#include <math.h> 43#endif 44#include <limits.h> 45#include <stdlib.h> 46#include <stdio.h> 47#include <string.h> 48#if defined(__linux__) && defined(__i386__) 49#include <fpu_control.h> 50#endif 51#include <float.h> 52#include <stdarg.h> 53 54 55#ifdef __cplusplus 56extern "C" { 57#endif 58 59 60/** 61 * Get standard integer types 62 */ 63#if defined(_MSC_VER) 64 typedef __int8 int8_t; 65 typedef unsigned __int8 uint8_t; 66 typedef __int16 int16_t; 67 typedef unsigned __int16 uint16_t; 68# ifndef __eglplatform_h_ 69 typedef __int32 int32_t; 70# endif 71 typedef unsigned __int32 uint32_t; 72 typedef __int64 int64_t; 73 typedef unsigned __int64 uint64_t; 74 75# if defined(_WIN64) 76 typedef __int64 intptr_t; 77 typedef unsigned __int64 uintptr_t; 78# else 79 typedef __int32 intptr_t; 80 typedef unsigned __int32 uintptr_t; 81# endif 82 83# define INT64_C(__val) __val##i64 84# define UINT64_C(__val) __val##ui64 85#else 86# include <stdint.h> 87#endif 88 89 90/** 91 * Sun compilers define __i386 instead of the gcc-style __i386__ 92 */ 93#ifdef __SUNPRO_C 94# if !defined(__i386__) && defined(__i386) 95# define __i386__ 96# elif !defined(__amd64__) && defined(__amd64) 97# define __amd64__ 98# elif !defined(__sparc__) && defined(__sparc) 99# define __sparc__ 100# endif 101# if !defined(__volatile) 102# define __volatile volatile 103# endif 104#endif 105 106 107/** 108 * finite macro. 109 */ 110#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(BUILD_FOR_SNAP) 111# define __WIN32__ 112# define finite _finite 113#endif 114#if defined(__WATCOMC__) 115# define finite _finite 116# pragma disable_message(201) /* Disable unreachable code warnings */ 117#endif 118 119 120/** 121 * Disable assorted warnings 122 */ 123#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) && !defined(BUILD_FOR_SNAP) 124# if !defined(__GNUC__) /* mingw environment */ 125# pragma warning( disable : 4068 ) /* unknown pragma */ 126# pragma warning( disable : 4710 ) /* function 'foo' not inlined */ 127# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */ 128# pragma warning( disable : 4127 ) /* conditional expression is constant */ 129# if defined(MESA_MINWARN) 130# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */ 131# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */ 132# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */ 133# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */ 134# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */ 135# endif 136# endif 137#endif 138 139 140/** 141 * Function inlining 142 */ 143#if defined(__GNUC__) 144# define INLINE __inline__ 145#elif defined(__MSC__) 146# define INLINE __inline 147#elif defined(_MSC_VER) 148# define INLINE __inline 149#elif defined(__ICL) 150# define INLINE __inline 151#elif defined(__INTEL_COMPILER) 152# define INLINE inline 153#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) 154# define INLINE __inline 155#elif defined(__SUNPRO_C) && defined(__C99FEATURES__) 156# define INLINE inline 157# define __inline inline 158# define __inline__ inline 159#elif (__STDC_VERSION__ >= 199901L) /* C99 */ 160# define INLINE inline 161#else 162# define INLINE 163#endif 164 165 166/** 167 * PUBLIC/USED macros 168 * 169 * If we build the library with gcc's -fvisibility=hidden flag, we'll 170 * use the PUBLIC macro to mark functions that are to be exported. 171 * 172 * We also need to define a USED attribute, so the optimizer doesn't 173 * inline a static function that we later use in an alias. - ajax 174 */ 175#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 176# define PUBLIC __attribute__((visibility("default"))) 177# define USED __attribute__((used)) 178#else 179# define PUBLIC 180# define USED 181#endif 182 183 184/** 185 * Some compilers don't like some of Mesa's const usage. In those places use 186 * CONST instead of const. Pass -DNO_CONST to compilers where this matters. 187 */ 188#ifdef NO_CONST 189# define CONST 190#else 191# define CONST const 192#endif 193 194 195/** 196 * __builtin_expect macros 197 */ 198#if (!defined(__GNUC__) || __GNUC__ < 3) && (!defined(__IBMC__) || __IBMC__ < 900) 199# define __builtin_expect(x, y) x 200#endif 201 202 203/** 204 * The __FUNCTION__ gcc variable is generally only used for debugging. 205 * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. 206 * Don't define it if using a newer Windows compiler. 207 */ 208#ifndef __FUNCTION__ 209# if defined(__VMS) 210# define __FUNCTION__ "VMS$NL:" 211# elif ((!defined __GNUC__) || (__GNUC__ < 2)) && (!defined __xlC__) && \ 212 (!defined(_MSC_VER) || _MSC_VER < 1300) 213# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ 214 (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 215# define __FUNCTION__ __func__ 216# else 217# define __FUNCTION__ "<unknown>" 218# endif 219# endif 220#endif 221 222 223/** 224 * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN. 225 * Do not use them unless absolutely necessary! 226 * Try to use a runtime test instead. 227 * For now, only used by some DRI hardware drivers for color/texel packing. 228 */ 229#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN 230#if defined(__linux__) 231#include <byteswap.h> 232#define CPU_TO_LE32( x ) bswap_32( x ) 233#else /*__linux__*/ 234#include <sys/endian.h> 235#define CPU_TO_LE32( x ) bswap32( x ) 236#endif /*__linux__*/ 237#define MESA_BIG_ENDIAN 1 238#else 239#define CPU_TO_LE32( x ) ( x ) 240#define MESA_LITTLE_ENDIAN 1 241#endif 242#define LE32_TO_CPU( x ) CPU_TO_LE32( x ) 243 244 245 246#if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP) 247#define CAPI _cdecl 248#endif 249 250 251/** 252 * Create a macro so that asm functions can be linked into compilers other 253 * than GNU C 254 */ 255#ifndef _ASMAPI 256#if defined(WIN32) && !defined(BUILD_FOR_SNAP)/* was: !defined( __GNUC__ ) && !defined( VMS ) && !defined( __INTEL_COMPILER )*/ 257#define _ASMAPI __cdecl 258#else 259#define _ASMAPI 260#endif 261#ifdef PTR_DECL_IN_FRONT 262#define _ASMAPIP * _ASMAPI 263#else 264#define _ASMAPIP _ASMAPI * 265#endif 266#endif 267 268#ifdef USE_X86_ASM 269#define _NORMAPI _ASMAPI 270#define _NORMAPIP _ASMAPIP 271#else 272#define _NORMAPI 273#define _NORMAPIP * 274#endif 275 276 277/* This is a macro on IRIX */ 278#ifdef _P 279#undef _P 280#endif 281 282 283/* Turn off macro checking systems used by other libraries */ 284#ifdef CHECK 285#undef CHECK 286#endif 287 288 289/** 290 * ASSERT macro 291 */ 292#if !defined(_WIN32_WCE) 293#if defined(BUILD_FOR_SNAP) && defined(CHECKED) 294# define ASSERT(X) _CHECK(X) 295#elif defined(DEBUG) 296# define ASSERT(X) assert(X) 297#else 298# define ASSERT(X) 299#endif 300#endif 301 302 303#ifndef NULL 304#define NULL 0 305#endif 306 307 308/** 309 * LONGSTRING macro 310 * gcc -pedantic warns about long string literals, LONGSTRING silences that. 311 */ 312#if !defined(__GNUC__) || (__GNUC__ < 2) || \ 313 ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 7)) 314# define LONGSTRING 315#else 316# define LONGSTRING __extension__ 317#endif 318 319 320#ifndef M_PI 321#define M_PI (3.1415926536) 322#endif 323 324#ifndef M_E 325#define M_E (2.7182818284590452354) 326#endif 327 328#ifndef ONE_DIV_LN2 329#define ONE_DIV_LN2 (1.442695040888963456) 330#endif 331 332#ifndef ONE_DIV_SQRT_LN2 333#define ONE_DIV_SQRT_LN2 (1.201122408786449815) 334#endif 335 336#ifndef FLT_MAX_EXP 337#define FLT_MAX_EXP 128 338#endif 339 340 341/** 342 * USE_IEEE: Determine if we're using IEEE floating point 343 */ 344#if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ 345 defined(__s390x__) || defined(__powerpc__) || \ 346 defined(__x86_64__) || \ 347 defined(ia64) || defined(__ia64__) || \ 348 defined(__hppa__) || defined(hpux) || \ 349 defined(__mips) || defined(_MIPS_ARCH) || \ 350 defined(__arm__) || \ 351 defined(__sh__) || defined(__m32r__) || \ 352 (defined(__sun) && defined(_IEEE_754)) || \ 353 (defined(__alpha__) && (defined(__IEEE_FLOAT) || !defined(VMS))) 354#define USE_IEEE 355#define IEEE_ONE 0x3f800000 356#endif 357 358 359/** 360 * START/END_FAST_MATH macros: 361 * 362 * START_FAST_MATH: Set x86 FPU to faster, 32-bit precision mode (and save 363 * original mode to a temporary). 364 * END_FAST_MATH: Restore x86 FPU to original mode. 365 */ 366#if defined(__GNUC__) && defined(__i386__) 367/* 368 * Set the x86 FPU control word to guarentee only 32 bits of precision 369 * are stored in registers. Allowing the FPU to store more introduces 370 * differences between situations where numbers are pulled out of memory 371 * vs. situations where the compiler is able to optimize register usage. 372 * 373 * In the worst case, we force the compiler to use a memory access to 374 * truncate the float, by specifying the 'volatile' keyword. 375 */ 376/* Hardware default: All exceptions masked, extended double precision, 377 * round to nearest (IEEE compliant): 378 */ 379#define DEFAULT_X86_FPU 0x037f 380/* All exceptions masked, single precision, round to nearest: 381 */ 382#define FAST_X86_FPU 0x003f 383/* The fldcw instruction will cause any pending FP exceptions to be 384 * raised prior to entering the block, and we clear any pending 385 * exceptions before exiting the block. Hence, asm code has free 386 * reign over the FPU while in the fast math block. 387 */ 388#if defined(NO_FAST_MATH) 389#define START_FAST_MATH(x) \ 390do { \ 391 static GLuint mask = DEFAULT_X86_FPU; \ 392 __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ 393 __asm__ ( "fldcw %0" : : "m" (mask) ); \ 394} while (0) 395#else 396#define START_FAST_MATH(x) \ 397do { \ 398 static GLuint mask = FAST_X86_FPU; \ 399 __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ 400 __asm__ ( "fldcw %0" : : "m" (mask) ); \ 401} while (0) 402#endif 403/* Restore original FPU mode, and clear any exceptions that may have 404 * occurred in the FAST_MATH block. 405 */ 406#define END_FAST_MATH(x) \ 407do { \ 408 __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) ); \ 409} while (0) 410 411#elif defined(__WATCOMC__) && defined(__386__) 412#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */ 413#define FAST_X86_FPU 0x003f /* See GCC comments above */ 414void _watcom_start_fast_math(unsigned short *x,unsigned short *mask); 415#pragma aux _watcom_start_fast_math = \ 416 "fnstcw word ptr [eax]" \ 417 "fldcw word ptr [ecx]" \ 418 parm [eax] [ecx] \ 419 modify exact []; 420void _watcom_end_fast_math(unsigned short *x); 421#pragma aux _watcom_end_fast_math = \ 422 "fnclex" \ 423 "fldcw word ptr [eax]" \ 424 parm [eax] \ 425 modify exact []; 426#if defined(NO_FAST_MATH) 427#define START_FAST_MATH(x) \ 428do { \ 429 static GLushort mask = DEFAULT_X86_FPU; \ 430 _watcom_start_fast_math(&x,&mask); \ 431} while (0) 432#else 433#define START_FAST_MATH(x) \ 434do { \ 435 static GLushort mask = FAST_X86_FPU; \ 436 _watcom_start_fast_math(&x,&mask); \ 437} while (0) 438#endif 439#define END_FAST_MATH(x) _watcom_end_fast_math(&x) 440 441#elif defined(_MSC_VER) && defined(_M_IX86) 442#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */ 443#define FAST_X86_FPU 0x003f /* See GCC comments above */ 444#if defined(NO_FAST_MATH) 445#define START_FAST_MATH(x) do {\ 446 static GLuint mask = DEFAULT_X86_FPU;\ 447 __asm fnstcw word ptr [x]\ 448 __asm fldcw word ptr [mask]\ 449} while(0) 450#else 451#define START_FAST_MATH(x) do {\ 452 static GLuint mask = FAST_X86_FPU;\ 453 __asm fnstcw word ptr [x]\ 454 __asm fldcw word ptr [mask]\ 455} while(0) 456#endif 457#define END_FAST_MATH(x) do {\ 458 __asm fnclex\ 459 __asm fldcw word ptr [x]\ 460} while(0) 461 462#else 463#define START_FAST_MATH(x) x = 0 464#define END_FAST_MATH(x) (void)(x) 465#endif 466 467 468 469#define Elements(x) (sizeof(x)/sizeof(*(x))) 470 471 472 473 474#ifdef __cplusplus 475} 476#endif 477 478 479#endif /* COMPILER_H */ 480