Home | History | Annotate | Download | only in src
      1 // Copyright 2015, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #ifndef VIXL_GLOBALS_H
     28 #define VIXL_GLOBALS_H
     29 
     30 // Get standard C99 macros for integer types.
     31 #ifndef __STDC_CONSTANT_MACROS
     32 #define __STDC_CONSTANT_MACROS
     33 #endif
     34 
     35 #ifndef __STDC_LIMIT_MACROS
     36 #define __STDC_LIMIT_MACROS
     37 #endif
     38 
     39 #ifndef __STDC_FORMAT_MACROS
     40 #define __STDC_FORMAT_MACROS
     41 #endif
     42 
     43 extern "C" {
     44 #include <inttypes.h>
     45 #include <stdint.h>
     46 }
     47 
     48 #include <cassert>
     49 #include <cstdarg>
     50 #include <cstddef>
     51 #include <cstdio>
     52 #include <cstdlib>
     53 
     54 #include "platform-vixl.h"
     55 
     56 #ifdef VIXL_NEGATIVE_TESTING
     57 #include <sstream>
     58 #include <stdexcept>
     59 #include <string>
     60 #endif
     61 
     62 namespace vixl {
     63 
     64 typedef uint8_t byte;
     65 
     66 const int KBytes = 1024;
     67 const int MBytes = 1024 * KBytes;
     68 
     69 const int kBitsPerByte = 8;
     70 
     71 template <int SizeInBits>
     72 struct Unsigned;
     73 
     74 template <>
     75 struct Unsigned<32> {
     76   typedef uint32_t type;
     77 };
     78 
     79 template <>
     80 struct Unsigned<64> {
     81   typedef uint64_t type;
     82 };
     83 
     84 }  // namespace vixl
     85 
     86 // Detect the host's pointer size.
     87 #if (UINTPTR_MAX == UINT32_MAX)
     88 #define VIXL_HOST_POINTER_32
     89 #elif (UINTPTR_MAX == UINT64_MAX)
     90 #define VIXL_HOST_POINTER_64
     91 #else
     92 #error "Unsupported host pointer size."
     93 #endif
     94 
     95 #ifdef VIXL_NEGATIVE_TESTING
     96 #define VIXL_ABORT()                                                         \
     97   do {                                                                       \
     98     std::ostringstream oss;                                                  \
     99     oss << "Aborting in " << __FILE__ << ", line " << __LINE__ << std::endl; \
    100     throw std::runtime_error(oss.str());                                     \
    101   } while (false)
    102 #define VIXL_ABORT_WITH_MSG(msg)                                             \
    103   do {                                                                       \
    104     std::ostringstream oss;                                                  \
    105     oss << (msg) << "in " << __FILE__ << ", line " << __LINE__ << std::endl; \
    106     throw std::runtime_error(oss.str());                                     \
    107   } while (false)
    108 #define VIXL_CHECK(condition)                                \
    109   do {                                                       \
    110     if (!(condition)) {                                      \
    111       std::ostringstream oss;                                \
    112       oss << "Assertion failed (" #condition ")\nin ";       \
    113       oss << __FILE__ << ", line " << __LINE__ << std::endl; \
    114       throw std::runtime_error(oss.str());                   \
    115     }                                                        \
    116   } while (false)
    117 #else
    118 #define VIXL_ABORT()                                         \
    119   do {                                                       \
    120     printf("Aborting in %s, line %i\n", __FILE__, __LINE__); \
    121     abort();                                                 \
    122   } while (false)
    123 #define VIXL_ABORT_WITH_MSG(msg)                             \
    124   do {                                                       \
    125     printf("%sin %s, line %i\n", (msg), __FILE__, __LINE__); \
    126     abort();                                                 \
    127   } while (false)
    128 #define VIXL_CHECK(condition)                           \
    129   do {                                                  \
    130     if (!(condition)) {                                 \
    131       printf("Assertion failed (%s)\nin %s, line %i\n", \
    132              #condition,                                \
    133              __FILE__,                                  \
    134              __LINE__);                                 \
    135       abort();                                          \
    136     }                                                   \
    137   } while (false)
    138 #endif
    139 #ifdef VIXL_DEBUG
    140 #define VIXL_ASSERT(condition) VIXL_CHECK(condition)
    141 #define VIXL_UNIMPLEMENTED()               \
    142   do {                                     \
    143     VIXL_ABORT_WITH_MSG("UNIMPLEMENTED "); \
    144   } while (false)
    145 #define VIXL_UNREACHABLE()               \
    146   do {                                   \
    147     VIXL_ABORT_WITH_MSG("UNREACHABLE "); \
    148   } while (false)
    149 #else
    150 #define VIXL_ASSERT(condition) ((void)0)
    151 #define VIXL_UNIMPLEMENTED() ((void)0)
    152 #define VIXL_UNREACHABLE() ((void)0)
    153 #endif
    154 // This is not as powerful as template based assertions, but it is simple.
    155 // It assumes that the descriptions are unique. If this starts being a problem,
    156 // we can switch to a different implemention.
    157 #define VIXL_CONCAT(a, b) a##b
    158 #if __cplusplus >= 201103L
    159 #define VIXL_STATIC_ASSERT_LINE(line_unused, condition, message) \
    160   static_assert(condition, message)
    161 #else
    162 #define VIXL_STATIC_ASSERT_LINE(line, condition, message_unused)            \
    163   typedef char VIXL_CONCAT(STATIC_ASSERT_LINE_, line)[(condition) ? 1 : -1] \
    164       __attribute__((unused))
    165 #endif
    166 #define VIXL_STATIC_ASSERT(condition) \
    167   VIXL_STATIC_ASSERT_LINE(__LINE__, condition, "")
    168 #define VIXL_STATIC_ASSERT_MESSAGE(condition, message) \
    169   VIXL_STATIC_ASSERT_LINE(__LINE__, condition, message)
    170 
    171 #define VIXL_WARNING(message)                                          \
    172   do {                                                                 \
    173     printf("WARNING in %s, line %i: %s", __FILE__, __LINE__, message); \
    174   } while (false)
    175 
    176 template <typename T1>
    177 inline void USE(const T1&) {}
    178 
    179 template <typename T1, typename T2>
    180 inline void USE(const T1&, const T2&) {}
    181 
    182 template <typename T1, typename T2, typename T3>
    183 inline void USE(const T1&, const T2&, const T3&) {}
    184 
    185 template <typename T1, typename T2, typename T3, typename T4>
    186 inline void USE(const T1&, const T2&, const T3&, const T4&) {}
    187 
    188 #define VIXL_ALIGNMENT_EXCEPTION()            \
    189   do {                                        \
    190     fprintf(stderr, "ALIGNMENT EXCEPTION\t"); \
    191     VIXL_ABORT();                             \
    192   } while (0)
    193 
    194 // The clang::fallthrough attribute is used along with the Wimplicit-fallthrough
    195 // argument to annotate intentional fall-through between switch labels.
    196 // For more information please refer to:
    197 // http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
    198 #ifndef __has_warning
    199 #define __has_warning(x) 0
    200 #endif
    201 
    202 // Fallthrough annotation for Clang and C++11(201103L).
    203 #if __has_warning("-Wimplicit-fallthrough") && __cplusplus >= 201103L
    204 #define VIXL_FALLTHROUGH() [[clang::fallthrough]]
    205 // Fallthrough annotation for GCC >= 7.
    206 #elif __GNUC__ >= 7
    207 #define VIXL_FALLTHROUGH() __attribute__((fallthrough))
    208 #else
    209 #define VIXL_FALLTHROUGH() \
    210   do {                     \
    211   } while (0)
    212 #endif
    213 
    214 #if __cplusplus >= 201103L
    215 #define VIXL_NO_RETURN [[noreturn]]
    216 #else
    217 #define VIXL_NO_RETURN __attribute__((noreturn))
    218 #endif
    219 #ifdef VIXL_DEBUG
    220 #define VIXL_NO_RETURN_IN_DEBUG_MODE VIXL_NO_RETURN
    221 #else
    222 #define VIXL_NO_RETURN_IN_DEBUG_MODE
    223 #endif
    224 
    225 #if __cplusplus >= 201103L
    226 #define VIXL_OVERRIDE override
    227 #else
    228 #define VIXL_OVERRIDE
    229 #endif
    230 
    231 // Some functions might only be marked as "noreturn" for the DEBUG build. This
    232 // macro should be used for such cases (for more details see what
    233 // VIXL_UNREACHABLE expands to).
    234 #ifdef VIXL_DEBUG
    235 #define VIXL_DEBUG_NO_RETURN VIXL_NO_RETURN
    236 #else
    237 #define VIXL_DEBUG_NO_RETURN
    238 #endif
    239 
    240 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
    241 #ifndef VIXL_AARCH64_GENERATE_SIMULATOR_CODE
    242 #define VIXL_AARCH64_GENERATE_SIMULATOR_CODE 1
    243 #endif
    244 #else
    245 #ifndef VIXL_AARCH64_GENERATE_SIMULATOR_CODE
    246 #define VIXL_AARCH64_GENERATE_SIMULATOR_CODE 0
    247 #endif
    248 #if VIXL_AARCH64_GENERATE_SIMULATOR_CODE
    249 #warning "Generating Simulator instructions without Simulator support."
    250 #endif
    251 #endif
    252 
    253 // We do not have a simulator for AArch32, although we can pretend we do so that
    254 // tests that require running natively can be skipped.
    255 #ifndef __arm__
    256 #define VIXL_INCLUDE_SIMULATOR_AARCH32
    257 #ifndef VIXL_AARCH32_GENERATE_SIMULATOR_CODE
    258 #define VIXL_AARCH32_GENERATE_SIMULATOR_CODE 1
    259 #endif
    260 #else
    261 #ifndef VIXL_AARCH32_GENERATE_SIMULATOR_CODE
    262 #define VIXL_AARCH32_GENERATE_SIMULATOR_CODE 0
    263 #endif
    264 #endif
    265 
    266 #ifdef USE_SIMULATOR
    267 #error "Please see the release notes for USE_SIMULATOR."
    268 #endif
    269 
    270 // Target Architecture/ISA
    271 #ifdef VIXL_INCLUDE_TARGET_A64
    272 #define VIXL_INCLUDE_TARGET_AARCH64
    273 #endif
    274 
    275 #if defined(VIXL_INCLUDE_TARGET_A32) && defined(VIXL_INCLUDE_TARGET_T32)
    276 #define VIXL_INCLUDE_TARGET_AARCH32
    277 #elif defined(VIXL_INCLUDE_TARGET_A32)
    278 #define VIXL_INCLUDE_TARGET_A32_ONLY
    279 #else
    280 #define VIXL_INCLUDE_TARGET_T32_ONLY
    281 #endif
    282 
    283 
    284 #endif  // VIXL_GLOBALS_H
    285