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
43extern "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
62namespace vixl {
63
64typedef uint8_t byte;
65
66// Type for half-precision (16 bit) floating point numbers.
67typedef uint16_t float16;
68
69const int KBytes = 1024;
70const int MBytes = 1024 * KBytes;
71
72const int kBitsPerByte = 8;
73
74template <int SizeInBits>
75struct Unsigned;
76
77template <>
78struct Unsigned<32> {
79  typedef uint32_t type;
80};
81
82template <>
83struct 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
181template <typename T1>
182inline void USE(const T1&) {}
183
184template <typename T1, typename T2>
185inline void USE(const T1&, const T2&) {}
186
187template <typename T1, typename T2, typename T3>
188inline void USE(const T1&, const T2&, const T3&) {}
189
190template <typename T1, typename T2, typename T3, typename T4>
191inline 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