tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

attributes.h (6311B)


      1 /*
      2 * Copyright © 2018, VideoLAN and dav1d authors
      3 * Copyright © 2018, Two Orioles, LLC
      4 * All rights reserved.
      5 *
      6 * Redistribution and use in source and binary forms, with or without
      7 * modification, are permitted provided that the following conditions are met:
      8 *
      9 * 1. Redistributions of source code must retain the above copyright notice, this
     10 *    list of conditions and the following disclaimer.
     11 *
     12 * 2. Redistributions in binary form must reproduce the above copyright notice,
     13 *    this list of conditions and the following disclaimer in the documentation
     14 *    and/or other materials provided with the distribution.
     15 *
     16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 */
     27 
     28 #ifndef DAV1D_COMMON_ATTRIBUTES_H
     29 #define DAV1D_COMMON_ATTRIBUTES_H
     30 
     31 #include "config.h"
     32 
     33 #include <stddef.h>
     34 #include <assert.h>
     35 
     36 #ifndef __has_attribute
     37 #define __has_attribute(x) 0
     38 #endif
     39 
     40 #ifndef __has_feature
     41 #define __has_feature(x) 0
     42 #endif
     43 
     44 #ifdef __GNUC__
     45 #define ATTR_ALIAS __attribute__((may_alias))
     46 #if defined(__MINGW32__) && !defined(__clang__)
     47 #define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__gnu_printf__, fmt, attr)))
     48 #else
     49 #define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__printf__, fmt, attr)))
     50 #endif
     51 #define COLD __attribute__((cold))
     52 #else
     53 #define ATTR_ALIAS
     54 #define ATTR_FORMAT_PRINTF(fmt, attr)
     55 #define COLD
     56 #endif
     57 
     58 #if ARCH_X86_64
     59 /* x86-64 needs 32- and 64-byte alignment for AVX2 and AVX-512. */
     60 #define ALIGN_64_VAL 64
     61 #define ALIGN_32_VAL 32
     62 #define ALIGN_16_VAL 16
     63 #elif ARCH_AARCH64 || ARCH_ARM || ARCH_LOONGARCH || ARCH_PPC64LE || ARCH_X86_32
     64 /* ARM doesn't benefit from anything more than 16-byte alignment. */
     65 #define ALIGN_64_VAL 16
     66 #define ALIGN_32_VAL 16
     67 #define ALIGN_16_VAL 16
     68 #else
     69 /* No need for extra alignment on platforms without assembly. */
     70 #define ALIGN_64_VAL 8
     71 #define ALIGN_32_VAL 8
     72 #define ALIGN_16_VAL 8
     73 #endif
     74 
     75 /*
     76 * API for variables, struct members (ALIGN()) like:
     77 * uint8_t var[1][2][3][4]
     78 * becomes:
     79 * ALIGN(uint8_t var[1][2][3][4], alignment).
     80 */
     81 #ifdef _MSC_VER
     82 #define ALIGN(ll, a) \
     83    __declspec(align(a)) ll
     84 #else
     85 #define ALIGN(line, align) \
     86    line __attribute__((aligned(align)))
     87 #endif
     88 
     89 /*
     90 * API for stack alignment (ALIGN_STK_$align()) of variables like:
     91 * uint8_t var[1][2][3][4]
     92 * becomes:
     93 * ALIGN_STK_$align(uint8_t, var, 1, [2][3][4])
     94 */
     95 #define ALIGN_STK_64(type, var, sz1d, sznd) \
     96    ALIGN(type var[sz1d]sznd, ALIGN_64_VAL)
     97 #define ALIGN_STK_32(type, var, sz1d, sznd) \
     98    ALIGN(type var[sz1d]sznd, ALIGN_32_VAL)
     99 #define ALIGN_STK_16(type, var, sz1d, sznd) \
    100    ALIGN(type var[sz1d]sznd, ALIGN_16_VAL)
    101 
    102 /*
    103 * Forbid inlining of a function:
    104 * static NOINLINE void func() {}
    105 */
    106 #ifdef _MSC_VER
    107 #define NOINLINE __declspec(noinline)
    108 #elif __has_attribute(noclone)
    109 #define NOINLINE __attribute__((noinline, noclone))
    110 #else
    111 #define NOINLINE __attribute__((noinline))
    112 #endif
    113 
    114 #ifdef _MSC_VER
    115 #define ALWAYS_INLINE __forceinline
    116 #else
    117 #define ALWAYS_INLINE __attribute__((always_inline)) inline
    118 #endif
    119 
    120 #if (defined(__ELF__) || defined(__MACH__) || (defined(_WIN32) && defined(__clang__))) && __has_attribute(visibility)
    121 #define EXTERN extern __attribute__((visibility("hidden")))
    122 #else
    123 #define EXTERN extern
    124 #endif
    125 
    126 #if ARCH_X86_64 && __has_attribute(model)
    127 #define ATTR_MCMODEL_SMALL __attribute__((model("small")))
    128 #else
    129 #define ATTR_MCMODEL_SMALL
    130 #endif
    131 
    132 #ifdef __clang__
    133 #define NO_SANITIZE(x) __attribute__((no_sanitize(x)))
    134 #else
    135 #define NO_SANITIZE(x)
    136 #endif
    137 
    138 #if defined(NDEBUG) && (defined(__GNUC__) || defined(__clang__))
    139 #undef assert
    140 #define assert(x) do { if (!(x)) __builtin_unreachable(); } while (0)
    141 #elif defined(NDEBUG) && defined(_MSC_VER)
    142 #undef assert
    143 #define assert __assume
    144 #endif
    145 
    146 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
    147 #    define dav1d_uninit(x) x=x
    148 #else
    149 #    define dav1d_uninit(x) x
    150 #endif
    151 
    152 #if defined(_MSC_VER) && !defined(__clang__)
    153 #include <intrin.h>
    154 
    155 static inline int ctz(const unsigned int mask) {
    156    unsigned long idx;
    157    _BitScanForward(&idx, mask);
    158    return idx;
    159 }
    160 
    161 static inline int clz(const unsigned int mask) {
    162    unsigned long leading_zero = 0;
    163    _BitScanReverse(&leading_zero, mask);
    164    return (31 - leading_zero);
    165 }
    166 
    167 #ifdef _WIN64
    168 static inline int clzll(const unsigned long long mask) {
    169    unsigned long leading_zero = 0;
    170    _BitScanReverse64(&leading_zero, mask);
    171    return (63 - leading_zero);
    172 }
    173 #else /* _WIN64 */
    174 static inline int clzll(const unsigned long long mask) {
    175    if (mask >> 32)
    176        return clz((unsigned)(mask >> 32));
    177    else
    178        return clz((unsigned)mask) + 32;
    179 }
    180 #endif /* _WIN64 */
    181 #else /* !_MSC_VER */
    182 static inline int ctz(const unsigned int mask) {
    183    return __builtin_ctz(mask);
    184 }
    185 
    186 static inline int clz(const unsigned int mask) {
    187    return __builtin_clz(mask);
    188 }
    189 
    190 static inline int clzll(const unsigned long long mask) {
    191    return __builtin_clzll(mask);
    192 }
    193 #endif /* !_MSC_VER */
    194 
    195 #ifndef static_assert
    196 #define CHECK_OFFSET(type, field, name) \
    197    struct check_##type##_##field { int x[(name == offsetof(type, field)) ? 1 : -1]; }
    198 #define CHECK_SIZE(type, size) \
    199    struct check_##type##_size { int x[(size == sizeof(type)) ? 1 : -1]; }
    200 #else
    201 #define CHECK_OFFSET(type, field, name) \
    202    static_assert(name == offsetof(type, field), #field)
    203 #define CHECK_SIZE(type, size) \
    204    static_assert(size == sizeof(type), #type)
    205 #endif
    206 
    207 #ifdef _MSC_VER
    208 #define PACKED(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
    209 #else
    210 #define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
    211 #endif
    212 
    213 #endif /* DAV1D_COMMON_ATTRIBUTES_H */