1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2014 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#ifndef UTIL_MACROS_H
25bf215546Sopenharmony_ci#define UTIL_MACROS_H
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include <stdio.h>
28bf215546Sopenharmony_ci#include <assert.h>
29bf215546Sopenharmony_ci#include <stdint.h>
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci/* Compute the size of an array */
32bf215546Sopenharmony_ci#ifndef ARRAY_SIZE
33bf215546Sopenharmony_ci#  define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
34bf215546Sopenharmony_ci#endif
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci/* For compatibility with Clang's __has_builtin() */
37bf215546Sopenharmony_ci#ifndef __has_builtin
38bf215546Sopenharmony_ci#  define __has_builtin(x) 0
39bf215546Sopenharmony_ci#endif
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci#ifndef __has_attribute
42bf215546Sopenharmony_ci#  define __has_attribute(x) 0
43bf215546Sopenharmony_ci#endif
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci/**
46bf215546Sopenharmony_ci * __builtin_expect macros
47bf215546Sopenharmony_ci */
48bf215546Sopenharmony_ci#if !defined(HAVE___BUILTIN_EXPECT)
49bf215546Sopenharmony_ci#  define __builtin_expect(x, y) (x)
50bf215546Sopenharmony_ci#endif
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci#ifndef likely
53bf215546Sopenharmony_ci#  ifdef HAVE___BUILTIN_EXPECT
54bf215546Sopenharmony_ci#    define likely(x)   __builtin_expect(!!(x), 1)
55bf215546Sopenharmony_ci#    define unlikely(x) __builtin_expect(!!(x), 0)
56bf215546Sopenharmony_ci#  else
57bf215546Sopenharmony_ci#    define likely(x)   (x)
58bf215546Sopenharmony_ci#    define unlikely(x) (x)
59bf215546Sopenharmony_ci#  endif
60bf215546Sopenharmony_ci#endif
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci/**
63bf215546Sopenharmony_ci * __builtin_types_compatible_p compat
64bf215546Sopenharmony_ci */
65bf215546Sopenharmony_ci#if defined(__cplusplus) || !defined(HAVE___BUILTIN_TYPES_COMPATIBLE_P)
66bf215546Sopenharmony_ci#  define __builtin_types_compatible_p(type1, type2) (1)
67bf215546Sopenharmony_ci#endif
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci/**
70bf215546Sopenharmony_ci * Static (compile-time) assertion.
71bf215546Sopenharmony_ci */
72bf215546Sopenharmony_ci#define STATIC_ASSERT(cond) do { \
73bf215546Sopenharmony_ci   static_assert(cond, #cond); \
74bf215546Sopenharmony_ci} while (0)
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci/**
77bf215546Sopenharmony_ci * container_of - cast a member of a structure out to the containing structure
78bf215546Sopenharmony_ci * @ptr:        the pointer to the member.
79bf215546Sopenharmony_ci * @type:       the type of the container struct this is embedded in.
80bf215546Sopenharmony_ci * @member:     the name of the member within the struct.
81bf215546Sopenharmony_ci */
82bf215546Sopenharmony_ci#ifndef __GNUC__
83bf215546Sopenharmony_ci   /* a grown-up compiler is required for the extra type checking: */
84bf215546Sopenharmony_ci#  define container_of(ptr, type, member)                               \
85bf215546Sopenharmony_ci      (type*)((uint8_t *)ptr - offsetof(type, member))
86bf215546Sopenharmony_ci#else
87bf215546Sopenharmony_ci#  define __same_type(a, b) \
88bf215546Sopenharmony_ci      __builtin_types_compatible_p(__typeof__(a), __typeof__(b))
89bf215546Sopenharmony_ci#  define container_of(ptr, type, member) ({                            \
90bf215546Sopenharmony_ci         uint8_t *__mptr = (uint8_t *)(ptr);                            \
91bf215546Sopenharmony_ci         static_assert(__same_type(*(ptr), ((type *)0)->member) ||      \
92bf215546Sopenharmony_ci                       __same_type(*(ptr), void),                       \
93bf215546Sopenharmony_ci                       "pointer type mismatch in container_of()");      \
94bf215546Sopenharmony_ci         ((type *)(__mptr - offsetof(type, member)));                   \
95bf215546Sopenharmony_ci      })
96bf215546Sopenharmony_ci#endif
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci/**
99bf215546Sopenharmony_ci * Unreachable macro. Useful for suppressing "control reaches end of non-void
100bf215546Sopenharmony_ci * function" warnings.
101bf215546Sopenharmony_ci */
102bf215546Sopenharmony_ci#if defined(HAVE___BUILTIN_UNREACHABLE) || __has_builtin(__builtin_unreachable)
103bf215546Sopenharmony_ci#define unreachable(str)    \
104bf215546Sopenharmony_cido {                        \
105bf215546Sopenharmony_ci   assert(!str);            \
106bf215546Sopenharmony_ci   __builtin_unreachable(); \
107bf215546Sopenharmony_ci} while (0)
108bf215546Sopenharmony_ci#elif defined (_MSC_VER)
109bf215546Sopenharmony_ci#define unreachable(str)    \
110bf215546Sopenharmony_cido {                        \
111bf215546Sopenharmony_ci   assert(!str);            \
112bf215546Sopenharmony_ci   __assume(0);             \
113bf215546Sopenharmony_ci} while (0)
114bf215546Sopenharmony_ci#else
115bf215546Sopenharmony_ci#define unreachable(str) assert(!str)
116bf215546Sopenharmony_ci#endif
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci/**
119bf215546Sopenharmony_ci * Assume macro. Useful for expressing our assumptions to the compiler,
120bf215546Sopenharmony_ci * typically for purposes of silencing warnings.
121bf215546Sopenharmony_ci */
122bf215546Sopenharmony_ci#if __has_builtin(__builtin_assume)
123bf215546Sopenharmony_ci#define assume(expr)       \
124bf215546Sopenharmony_cido {                       \
125bf215546Sopenharmony_ci   assert(expr);           \
126bf215546Sopenharmony_ci   __builtin_assume(expr); \
127bf215546Sopenharmony_ci} while (0)
128bf215546Sopenharmony_ci#elif defined HAVE___BUILTIN_UNREACHABLE
129bf215546Sopenharmony_ci#define assume(expr) ((expr) ? ((void) 0) \
130bf215546Sopenharmony_ci                             : (assert(!"assumption failed"), \
131bf215546Sopenharmony_ci                                __builtin_unreachable()))
132bf215546Sopenharmony_ci#elif defined (_MSC_VER)
133bf215546Sopenharmony_ci#define assume(expr) __assume(expr)
134bf215546Sopenharmony_ci#else
135bf215546Sopenharmony_ci#define assume(expr) assert(expr)
136bf215546Sopenharmony_ci#endif
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci/* Attribute const is used for functions that have no effects other than their
139bf215546Sopenharmony_ci * return value, and only rely on the argument values to compute the return
140bf215546Sopenharmony_ci * value.  As a result, calls to it can be CSEed.  Note that using memory
141bf215546Sopenharmony_ci * pointed to by the arguments is not allowed for const functions.
142bf215546Sopenharmony_ci */
143bf215546Sopenharmony_ci#if !defined(__clang__) && defined(HAVE_FUNC_ATTRIBUTE_CONST)
144bf215546Sopenharmony_ci#define ATTRIBUTE_CONST __attribute__((__const__))
145bf215546Sopenharmony_ci#else
146bf215546Sopenharmony_ci#define ATTRIBUTE_CONST
147bf215546Sopenharmony_ci#endif
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_FLATTEN
150bf215546Sopenharmony_ci#define FLATTEN __attribute__((__flatten__))
151bf215546Sopenharmony_ci#else
152bf215546Sopenharmony_ci#define FLATTEN
153bf215546Sopenharmony_ci#endif
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT
156bf215546Sopenharmony_ci#if defined (__MINGW_PRINTF_FORMAT)
157bf215546Sopenharmony_ci# define PRINTFLIKE(f, a) __attribute__ ((format(__MINGW_PRINTF_FORMAT, f, a)))
158bf215546Sopenharmony_ci#else
159bf215546Sopenharmony_ci# define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
160bf215546Sopenharmony_ci#endif
161bf215546Sopenharmony_ci#else
162bf215546Sopenharmony_ci#define PRINTFLIKE(f, a)
163bf215546Sopenharmony_ci#endif
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
166bf215546Sopenharmony_ci#define MALLOCLIKE __attribute__((__malloc__))
167bf215546Sopenharmony_ci#else
168bf215546Sopenharmony_ci#define MALLOCLIKE
169bf215546Sopenharmony_ci#endif
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci/* Forced function inlining */
172bf215546Sopenharmony_ci/* Note: Clang also sets __GNUC__ (see other cases below) */
173bf215546Sopenharmony_ci#ifndef ALWAYS_INLINE
174bf215546Sopenharmony_ci#  if defined(__GNUC__)
175bf215546Sopenharmony_ci#    define ALWAYS_INLINE inline __attribute__((always_inline))
176bf215546Sopenharmony_ci#  elif defined(_MSC_VER)
177bf215546Sopenharmony_ci#    define ALWAYS_INLINE __forceinline
178bf215546Sopenharmony_ci#  else
179bf215546Sopenharmony_ci#    define ALWAYS_INLINE inline
180bf215546Sopenharmony_ci#  endif
181bf215546Sopenharmony_ci#endif
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci/* Used to optionally mark structures with misaligned elements or size as
184bf215546Sopenharmony_ci * packed, to trade off performance for space.
185bf215546Sopenharmony_ci */
186bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_PACKED
187bf215546Sopenharmony_ci#define PACKED __attribute__((__packed__))
188bf215546Sopenharmony_ci#else
189bf215546Sopenharmony_ci#define PACKED
190bf215546Sopenharmony_ci#endif
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci/* Attribute pure is used for functions that have no effects other than their
193bf215546Sopenharmony_ci * return value.  As a result, calls to it can be dead code eliminated.
194bf215546Sopenharmony_ci */
195bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_PURE
196bf215546Sopenharmony_ci#define ATTRIBUTE_PURE __attribute__((__pure__))
197bf215546Sopenharmony_ci#else
198bf215546Sopenharmony_ci#define ATTRIBUTE_PURE
199bf215546Sopenharmony_ci#endif
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL
202bf215546Sopenharmony_ci#define ATTRIBUTE_RETURNS_NONNULL __attribute__((__returns_nonnull__))
203bf215546Sopenharmony_ci#else
204bf215546Sopenharmony_ci#define ATTRIBUTE_RETURNS_NONNULL
205bf215546Sopenharmony_ci#endif
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci#ifndef NORETURN
208bf215546Sopenharmony_ci#  ifdef _MSC_VER
209bf215546Sopenharmony_ci#    define NORETURN __declspec(noreturn)
210bf215546Sopenharmony_ci#  elif defined HAVE_FUNC_ATTRIBUTE_NORETURN
211bf215546Sopenharmony_ci#    define NORETURN __attribute__((__noreturn__))
212bf215546Sopenharmony_ci#  else
213bf215546Sopenharmony_ci#    define NORETURN
214bf215546Sopenharmony_ci#  endif
215bf215546Sopenharmony_ci#endif
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci#ifdef _MSC_VER
218bf215546Sopenharmony_ci#define ALIGN16 __declspec(align(16))
219bf215546Sopenharmony_ci#else
220bf215546Sopenharmony_ci#define ALIGN16 __attribute__((aligned(16)))
221bf215546Sopenharmony_ci#endif
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci#ifdef __cplusplus
224bf215546Sopenharmony_ci/**
225bf215546Sopenharmony_ci * Macro function that evaluates to true if T is a trivially
226bf215546Sopenharmony_ci * destructible type -- that is, if its (non-virtual) destructor
227bf215546Sopenharmony_ci * performs no action and all member variables and base classes are
228bf215546Sopenharmony_ci * trivially destructible themselves.
229bf215546Sopenharmony_ci */
230bf215546Sopenharmony_ci#   if (defined(__clang__) && defined(__has_feature))
231bf215546Sopenharmony_ci#      if __has_feature(has_trivial_destructor)
232bf215546Sopenharmony_ci#         define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
233bf215546Sopenharmony_ci#      endif
234bf215546Sopenharmony_ci#   elif defined(__GNUC__)
235bf215546Sopenharmony_ci#      if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
236bf215546Sopenharmony_ci#         define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
237bf215546Sopenharmony_ci#      endif
238bf215546Sopenharmony_ci#   elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
239bf215546Sopenharmony_ci#      define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
240bf215546Sopenharmony_ci#   endif
241bf215546Sopenharmony_ci#   ifndef HAS_TRIVIAL_DESTRUCTOR
242bf215546Sopenharmony_ci       /* It's always safe (if inefficient) to assume that a
243bf215546Sopenharmony_ci        * destructor is non-trivial.
244bf215546Sopenharmony_ci        */
245bf215546Sopenharmony_ci#      define HAS_TRIVIAL_DESTRUCTOR(T) (false)
246bf215546Sopenharmony_ci#   endif
247bf215546Sopenharmony_ci#endif
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci/**
250bf215546Sopenharmony_ci * PUBLIC/USED macros
251bf215546Sopenharmony_ci *
252bf215546Sopenharmony_ci * If we build the library with gcc's -fvisibility=hidden flag, we'll
253bf215546Sopenharmony_ci * use the PUBLIC macro to mark functions that are to be exported.
254bf215546Sopenharmony_ci *
255bf215546Sopenharmony_ci * We also need to define a USED attribute, so the optimizer doesn't
256bf215546Sopenharmony_ci * inline a static function that we later use in an alias. - ajax
257bf215546Sopenharmony_ci */
258bf215546Sopenharmony_ci#ifndef PUBLIC
259bf215546Sopenharmony_ci#  if defined(_WIN32)
260bf215546Sopenharmony_ci#    define PUBLIC __declspec(dllexport)
261bf215546Sopenharmony_ci#    define USED
262bf215546Sopenharmony_ci#  elif defined(__GNUC__)
263bf215546Sopenharmony_ci#    define PUBLIC __attribute__((visibility("default")))
264bf215546Sopenharmony_ci#    define USED __attribute__((used))
265bf215546Sopenharmony_ci#  else
266bf215546Sopenharmony_ci#    define PUBLIC
267bf215546Sopenharmony_ci#    define USED
268bf215546Sopenharmony_ci#  endif
269bf215546Sopenharmony_ci#endif
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci/**
272bf215546Sopenharmony_ci * UNUSED marks variables (or sometimes functions) that have to be defined,
273bf215546Sopenharmony_ci * but are sometimes (or always) unused beyond that. A common case is for
274bf215546Sopenharmony_ci * a function parameter to be used in some build configurations but not others.
275bf215546Sopenharmony_ci * Another case is fallback vfuncs that don't do anything with their params.
276bf215546Sopenharmony_ci *
277bf215546Sopenharmony_ci * Note that this should not be used for identifiers used in `assert()`;
278bf215546Sopenharmony_ci * see ASSERTED below.
279bf215546Sopenharmony_ci */
280bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_UNUSED
281bf215546Sopenharmony_ci#define UNUSED __attribute__((unused))
282bf215546Sopenharmony_ci#elif defined (_MSC_VER)
283bf215546Sopenharmony_ci#define UNUSED __pragma(warning(suppress:4100 4101))
284bf215546Sopenharmony_ci#else
285bf215546Sopenharmony_ci#define UNUSED
286bf215546Sopenharmony_ci#endif
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_ci/**
289bf215546Sopenharmony_ci * Use ASSERTED to indicate that an identifier is unused outside of an `assert()`,
290bf215546Sopenharmony_ci * so that assert-free builds don't get "unused variable" warnings.
291bf215546Sopenharmony_ci */
292bf215546Sopenharmony_ci#ifdef NDEBUG
293bf215546Sopenharmony_ci#define ASSERTED UNUSED
294bf215546Sopenharmony_ci#else
295bf215546Sopenharmony_ci#define ASSERTED
296bf215546Sopenharmony_ci#endif
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
299bf215546Sopenharmony_ci#define MUST_CHECK __attribute__((warn_unused_result))
300bf215546Sopenharmony_ci#else
301bf215546Sopenharmony_ci#define MUST_CHECK
302bf215546Sopenharmony_ci#endif
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci#if defined(__GNUC__)
305bf215546Sopenharmony_ci#define ATTRIBUTE_NOINLINE __attribute__((noinline))
306bf215546Sopenharmony_ci#elif defined(_MSC_VER)
307bf215546Sopenharmony_ci#define ATTRIBUTE_NOINLINE __declspec(noinline)
308bf215546Sopenharmony_ci#else
309bf215546Sopenharmony_ci#define ATTRIBUTE_NOINLINE
310bf215546Sopenharmony_ci#endif
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci/* Use as: enum name { X, Y } ENUM_PACKED; */
313bf215546Sopenharmony_ci#if defined(__GNUC__)
314bf215546Sopenharmony_ci#define ENUM_PACKED __attribute__((packed))
315bf215546Sopenharmony_ci#else
316bf215546Sopenharmony_ci#define ENUM_PACKED
317bf215546Sopenharmony_ci#endif
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci/**
321bf215546Sopenharmony_ci * Check that STRUCT::FIELD can hold MAXVAL.  We use a lot of bitfields
322bf215546Sopenharmony_ci * in Mesa/gallium.  We have to be sure they're of sufficient size to
323bf215546Sopenharmony_ci * hold the largest expected value.
324bf215546Sopenharmony_ci * Note that with MSVC, enums are signed and enum bitfields need one extra
325bf215546Sopenharmony_ci * high bit (always zero) to ensure the max value is handled correctly.
326bf215546Sopenharmony_ci * This macro will detect that with MSVC, but not GCC.
327bf215546Sopenharmony_ci */
328bf215546Sopenharmony_ci#define ASSERT_BITFIELD_SIZE(STRUCT, FIELD, MAXVAL) \
329bf215546Sopenharmony_ci   do { \
330bf215546Sopenharmony_ci      ASSERTED STRUCT s; \
331bf215546Sopenharmony_ci      s.FIELD = (MAXVAL); \
332bf215546Sopenharmony_ci      assert((int) s.FIELD == (MAXVAL) && "Insufficient bitfield size!"); \
333bf215546Sopenharmony_ci   } while (0)
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci/** Compute ceiling of integer quotient of A divided by B. */
337bf215546Sopenharmony_ci#define DIV_ROUND_UP( A, B )  ( ((A) + (B) - 1) / (B) )
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci/** Clamp X to [MIN,MAX].  Turn NaN into MIN, arbitrarily. */
340bf215546Sopenharmony_ci#define CLAMP( X, MIN, MAX )  ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) )
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci/* Syntax sugar occuring frequently in graphics code */
343bf215546Sopenharmony_ci#define SATURATE( X ) CLAMP(X, 0.0f, 1.0f)
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci/** Minimum of two values: */
346bf215546Sopenharmony_ci#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci/** Maximum of two values: */
349bf215546Sopenharmony_ci#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci/** Minimum and maximum of three values: */
352bf215546Sopenharmony_ci#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
353bf215546Sopenharmony_ci#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci/** Align a value to a power of two */
356bf215546Sopenharmony_ci#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1))
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci/** Checks is a value is a power of two. Does not handle zero. */
359bf215546Sopenharmony_ci#define IS_POT(v) (((v) & ((v) - 1)) == 0)
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci/**
362bf215546Sopenharmony_ci * Macro for declaring an explicit conversion operator.  Defaults to an
363bf215546Sopenharmony_ci * implicit conversion if C++11 is not supported.
364bf215546Sopenharmony_ci */
365bf215546Sopenharmony_ci#if __cplusplus >= 201103L
366bf215546Sopenharmony_ci#define EXPLICIT_CONVERSION explicit
367bf215546Sopenharmony_ci#elif defined(__cplusplus)
368bf215546Sopenharmony_ci#define EXPLICIT_CONVERSION
369bf215546Sopenharmony_ci#endif
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci/** Set a single bit */
372bf215546Sopenharmony_ci#define BITFIELD_BIT(b)      (1u << (b))
373bf215546Sopenharmony_ci/** Set all bits up to excluding bit b */
374bf215546Sopenharmony_ci#define BITFIELD_MASK(b)      \
375bf215546Sopenharmony_ci   ((b) == 32 ? (~0u) : BITFIELD_BIT((b) % 32) - 1)
376bf215546Sopenharmony_ci/** Set count bits starting from bit b  */
377bf215546Sopenharmony_ci#define BITFIELD_RANGE(b, count) \
378bf215546Sopenharmony_ci   (BITFIELD_MASK((b) + (count)) & ~BITFIELD_MASK(b))
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci/** Set a single bit */
381bf215546Sopenharmony_ci#define BITFIELD64_BIT(b)      (1ull << (b))
382bf215546Sopenharmony_ci/** Set all bits up to excluding bit b */
383bf215546Sopenharmony_ci#define BITFIELD64_MASK(b)      \
384bf215546Sopenharmony_ci   ((b) == 64 ? (~0ull) : BITFIELD64_BIT(b) - 1)
385bf215546Sopenharmony_ci/** Set count bits starting from bit b  */
386bf215546Sopenharmony_ci#define BITFIELD64_RANGE(b, count) \
387bf215546Sopenharmony_ci   (BITFIELD64_MASK((b) + (count)) & ~BITFIELD64_MASK(b))
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_cistatic inline int64_t
390bf215546Sopenharmony_ciu_intN_max(unsigned bit_size)
391bf215546Sopenharmony_ci{
392bf215546Sopenharmony_ci   assert(bit_size <= 64 && bit_size > 0);
393bf215546Sopenharmony_ci   return INT64_MAX >> (64 - bit_size);
394bf215546Sopenharmony_ci}
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_cistatic inline int64_t
397bf215546Sopenharmony_ciu_intN_min(unsigned bit_size)
398bf215546Sopenharmony_ci{
399bf215546Sopenharmony_ci   /* On 2's compliment platforms, which is every platform Mesa is likely to
400bf215546Sopenharmony_ci    * every worry about, stdint.h generally calculated INT##_MIN in this
401bf215546Sopenharmony_ci    * manner.
402bf215546Sopenharmony_ci    */
403bf215546Sopenharmony_ci   return (-u_intN_max(bit_size)) - 1;
404bf215546Sopenharmony_ci}
405bf215546Sopenharmony_ci
406bf215546Sopenharmony_cistatic inline uint64_t
407bf215546Sopenharmony_ciu_uintN_max(unsigned bit_size)
408bf215546Sopenharmony_ci{
409bf215546Sopenharmony_ci   assert(bit_size <= 64 && bit_size > 0);
410bf215546Sopenharmony_ci   return UINT64_MAX >> (64 - bit_size);
411bf215546Sopenharmony_ci}
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci#ifndef __cplusplus
414bf215546Sopenharmony_ci#ifdef _MSC_VER
415bf215546Sopenharmony_ci#define alignof _Alignof
416bf215546Sopenharmony_ci#define alignas _Alignas
417bf215546Sopenharmony_ci#else
418bf215546Sopenharmony_ci#include <stdalign.h>
419bf215546Sopenharmony_ci#endif
420bf215546Sopenharmony_ci#endif
421bf215546Sopenharmony_ci
422bf215546Sopenharmony_ci/* Macros for static type-safety checking.
423bf215546Sopenharmony_ci *
424bf215546Sopenharmony_ci * https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
425bf215546Sopenharmony_ci */
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ci#if __has_attribute(capability)
428bf215546Sopenharmony_citypedef int __attribute__((capability("mutex"))) lock_cap_t;
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci#define guarded_by(l) __attribute__((guarded_by(l)))
431bf215546Sopenharmony_ci#define acquire_cap(l) __attribute((acquire_capability(l), no_thread_safety_analysis))
432bf215546Sopenharmony_ci#define release_cap(l) __attribute((release_capability(l), no_thread_safety_analysis))
433bf215546Sopenharmony_ci#define assert_cap(l) __attribute((assert_capability(l), no_thread_safety_analysis))
434bf215546Sopenharmony_ci#define requires_cap(l) __attribute((requires_capability(l)))
435bf215546Sopenharmony_ci#define disable_thread_safety_analysis __attribute((no_thread_safety_analysis))
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci#else
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_citypedef int lock_cap_t;
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci#define guarded_by(l)
442bf215546Sopenharmony_ci#define acquire_cap(l)
443bf215546Sopenharmony_ci#define release_cap(l)
444bf215546Sopenharmony_ci#define assert_cap(l)
445bf215546Sopenharmony_ci#define requires_cap(l)
446bf215546Sopenharmony_ci#define disable_thread_safety_analysis
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci#endif
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ci/* TODO: this could be different on non-x86 architectures. */
451bf215546Sopenharmony_ci#define CACHE_LINE_SIZE 64
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci#define DO_PRAGMA(X) _Pragma (#X)
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_ci#if defined(__clang__)
456bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_PUSH       _Pragma("clang diagnostic push")
457bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_POP        _Pragma("clang diagnostic pop")
458bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_ERROR(X)   DO_PRAGMA( clang diagnostic error #X )
459bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_WARNING(X) DO_PRAGMA( clang diagnostic warning #X )
460bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_IGNORED(X) DO_PRAGMA( clang diagnostic ignored #X )
461bf215546Sopenharmony_ci#elif defined(__GNUC__)
462bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_PUSH       _Pragma("GCC diagnostic push")
463bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_POP        _Pragma("GCC diagnostic pop")
464bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_ERROR(X)   DO_PRAGMA( GCC diagnostic error #X )
465bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_WARNING(X) DO_PRAGMA( GCC diagnostic warning #X )
466bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_IGNORED(X) DO_PRAGMA( GCC diagnostic ignored #X )
467bf215546Sopenharmony_ci#else
468bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_PUSH
469bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_POP
470bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_ERROR(X)
471bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_WARNING(X)
472bf215546Sopenharmony_ci#define PRAGMA_DIAGNOSTIC_IGNORED(X)
473bf215546Sopenharmony_ci#endif
474bf215546Sopenharmony_ci
475bf215546Sopenharmony_ci#endif /* UTIL_MACROS_H */
476