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 // Type for half-precision (16 bit) floating point numbers. 67 typedef uint16_t float16; 68 69 const int KBytes = 1024; 70 const int MBytes = 1024 * KBytes; 71 72 const int kBitsPerByte = 8; 73 74 template <int SizeInBits> 75 struct Unsigned; 76 77 template <> 78 struct Unsigned<32> { 79 typedef uint32_t type; 80 }; 81 82 template <> 83 struct Unsigned<64> { 84 typedef uint64_t type; 85 }; 86 87 } // namespace vixl 88 89 // Detect the host's pointer size. 90 #if (UINTPTR_MAX == UINT32_MAX) 91 #define VIXL_HOST_POINTER_32 92 #elif (UINTPTR_MAX == UINT64_MAX) 93 #define VIXL_HOST_POINTER_64 94 #else 95 #error "Unsupported host pointer size." 96 #endif 97 98 #ifdef VIXL_NEGATIVE_TESTING 99 #define VIXL_ABORT() \ 100 do { \ 101 std::ostringstream oss; \ 102 oss << "Aborting in " << __FILE__ << ", line " << __LINE__ << std::endl; \ 103 throw std::runtime_error(oss.str()); \ 104 } while (false) 105 #define VIXL_ABORT_WITH_MSG(msg) \ 106 do { \ 107 std::ostringstream oss; \ 108 oss << (msg) << "in " << __FILE__ << ", line " << __LINE__ << std::endl; \ 109 throw std::runtime_error(oss.str()); \ 110 } while (false) 111 #define VIXL_CHECK(condition) \ 112 do { \ 113 if (!(condition)) { \ 114 std::ostringstream oss; \ 115 oss << "Assertion failed (" #condition ")\nin "; \ 116 oss << __FILE__ << ", line " << __LINE__ << std::endl; \ 117 throw std::runtime_error(oss.str()); \ 118 } \ 119 } while (false) 120 #define VIXL_THROW_IN_NEGATIVE_TESTING_MODE(error) throw(error) 121 #else 122 #define VIXL_ABORT() \ 123 do { \ 124 printf("Aborting in %s, line %i\n", __FILE__, __LINE__); \ 125 abort(); \ 126 } while (false) 127 #define VIXL_ABORT_WITH_MSG(msg) \ 128 do { \ 129 printf("%sin %s, line %i\n", (msg), __FILE__, __LINE__); \ 130 abort(); \ 131 } while (false) 132 #define VIXL_CHECK(condition) \ 133 do { \ 134 if (!(condition)) { \ 135 printf("Assertion failed (%s)\nin %s, line %i\n", \ 136 #condition, \ 137 __FILE__, \ 138 __LINE__); \ 139 abort(); \ 140 } \ 141 } while (false) 142 #define VIXL_THROW_IN_NEGATIVE_TESTING_MODE(error) 143 #endif 144 #ifdef VIXL_DEBUG 145 #define VIXL_ASSERT(condition) VIXL_CHECK(condition) 146 #define VIXL_UNIMPLEMENTED() \ 147 do { \ 148 VIXL_ABORT_WITH_MSG("UNIMPLEMENTED "); \ 149 } while (false) 150 #define VIXL_UNREACHABLE() \ 151 do { \ 152 VIXL_ABORT_WITH_MSG("UNREACHABLE "); \ 153 } while (false) 154 #else 155 #define VIXL_ASSERT(condition) ((void)0) 156 #define VIXL_UNIMPLEMENTED() ((void)0) 157 #define VIXL_UNREACHABLE() ((void)0) 158 #endif 159 // This is not as powerful as template based assertions, but it is simple. 160 // It assumes that the descriptions are unique. If this starts being a problem, 161 // we can switch to a different implemention. 162 #define VIXL_CONCAT(a, b) a##b 163 #if __cplusplus >= 201103L 164 #define VIXL_STATIC_ASSERT_LINE(line_unused, condition, message) \ 165 static_assert(condition, message) 166 #else 167 #define VIXL_STATIC_ASSERT_LINE(line, condition, message_unused) \ 168 typedef char VIXL_CONCAT(STATIC_ASSERT_LINE_, line)[(condition) ? 1 : -1] \ 169 __attribute__((unused)) 170 #endif 171 #define VIXL_STATIC_ASSERT(condition) \ 172 VIXL_STATIC_ASSERT_LINE(__LINE__, condition, "") 173 #define VIXL_STATIC_ASSERT_MESSAGE(condition, message) \ 174 VIXL_STATIC_ASSERT_LINE(__LINE__, condition, message) 175 176 #define VIXL_WARNING(message) \ 177 do { \ 178 printf("WARNING in %s, line %i: %s", __FILE__, __LINE__, message); \ 179 } while (false) 180 181 template <typename T1> 182 inline void USE(const T1&) {} 183 184 template <typename T1, typename T2> 185 inline void USE(const T1&, const T2&) {} 186 187 template <typename T1, typename T2, typename T3> 188 inline void USE(const T1&, const T2&, const T3&) {} 189 190 template <typename T1, typename T2, typename T3, typename T4> 191 inline void USE(const T1&, const T2&, const T3&, const T4&) {} 192 193 #define VIXL_ALIGNMENT_EXCEPTION() \ 194 do { \ 195 fprintf(stderr, "ALIGNMENT EXCEPTION\t"); \ 196 VIXL_ABORT(); \ 197 } while (0) 198 199 // The clang::fallthrough attribute is used along with the Wimplicit-fallthrough 200 // argument to annotate intentional fall-through between switch labels. 201 // For more information please refer to: 202 // http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough 203 #ifndef __has_warning 204 #define __has_warning(x) 0 205 #endif 206 207 // Note: This option is only available for Clang. And will only be enabled for 208 // C++11(201103L). 209 #if __has_warning("-Wimplicit-fallthrough") && __cplusplus >= 201103L 210 #define VIXL_FALLTHROUGH() [[clang::fallthrough]] 211 #else 212 #define VIXL_FALLTHROUGH() \ 213 do { \ 214 } while (0) 215 #endif 216 217 #if __cplusplus >= 201103L 218 #define VIXL_NO_RETURN [[noreturn]] 219 #else 220 #define VIXL_NO_RETURN __attribute__((noreturn)) 221 #endif 222 #ifdef VIXL_DEBUG 223 #define VIXL_NO_RETURN_IN_DEBUG_MODE VIXL_NO_RETURN 224 #else 225 #define VIXL_NO_RETURN_IN_DEBUG_MODE 226 #endif 227 228 #if __cplusplus >= 201103L 229 #define VIXL_OVERRIDE override 230 #else 231 #define VIXL_OVERRIDE 232 #endif 233 234 // Some functions might only be marked as "noreturn" for the DEBUG build. This 235 // macro should be used for such cases (for more details see what 236 // VIXL_UNREACHABLE expands to). 237 #ifdef VIXL_DEBUG 238 #define VIXL_DEBUG_NO_RETURN VIXL_NO_RETURN 239 #else 240 #define VIXL_DEBUG_NO_RETURN 241 #endif 242 243 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 244 #ifndef VIXL_AARCH64_GENERATE_SIMULATOR_CODE 245 #define VIXL_AARCH64_GENERATE_SIMULATOR_CODE 1 246 #endif 247 #else 248 #ifndef VIXL_AARCH64_GENERATE_SIMULATOR_CODE 249 #define VIXL_AARCH64_GENERATE_SIMULATOR_CODE 0 250 #endif 251 #if VIXL_AARCH64_GENERATE_SIMULATOR_CODE 252 #warning "Generating Simulator instructions without Simulator support." 253 #endif 254 #endif 255 256 // We do not have a simulator for AArch32, although we can pretend we do so that 257 // tests that require running natively can be skipped. 258 #ifndef __arm__ 259 #define VIXL_INCLUDE_SIMULATOR_AARCH32 260 #ifndef VIXL_AARCH32_GENERATE_SIMULATOR_CODE 261 #define VIXL_AARCH32_GENERATE_SIMULATOR_CODE 1 262 #endif 263 #else 264 #ifndef VIXL_AARCH32_GENERATE_SIMULATOR_CODE 265 #define VIXL_AARCH32_GENERATE_SIMULATOR_CODE 0 266 #endif 267 #endif 268 269 #ifdef USE_SIMULATOR 270 #error "Please see the release notes for USE_SIMULATOR." 271 #endif 272 273 // Target Architecture/ISA 274 #ifdef VIXL_INCLUDE_TARGET_A64 275 #define VIXL_INCLUDE_TARGET_AARCH64 276 #endif 277 278 #if defined(VIXL_INCLUDE_TARGET_A32) && defined(VIXL_INCLUDE_TARGET_T32) 279 #define VIXL_INCLUDE_TARGET_AARCH32 280 #elif defined(VIXL_INCLUDE_TARGET_A32) 281 #define VIXL_INCLUDE_TARGET_A32_ONLY 282 #else 283 #define VIXL_INCLUDE_TARGET_T32_ONLY 284 #endif 285 286 287 #endif // VIXL_GLOBALS_H 288