]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | /* |
2 | * Distributed under the Boost Software License, Version 1.0. | |
3 | * (See accompanying file LICENSE_1_0.txt or copy at | |
4 | * http://www.boost.org/LICENSE_1_0.txt) | |
5 | * | |
20effc67 TL |
6 | * Copyright (c) 2009 Helge Bahmann |
7 | * Copyright (c) 2009 Phil Endecott | |
8 | * Copyright (c) 2013 Tim Blechmann | |
9 | * ARM Code by Phil Endecott, based on other architectures. | |
10 | * Copyright (c) 2014, 2020 Andrey Semashev | |
b32b8144 FG |
11 | */ |
12 | /*! | |
20effc67 | 13 | * \file atomic/detail/caps_arch_gcc_arm.hpp |
b32b8144 | 14 | * |
20effc67 | 15 | * This header defines feature capabilities macros |
b32b8144 FG |
16 | */ |
17 | ||
20effc67 TL |
18 | #ifndef BOOST_ATOMIC_DETAIL_CAPS_ARCH_GCC_ARM_HPP_INCLUDED_ |
19 | #define BOOST_ATOMIC_DETAIL_CAPS_ARCH_GCC_ARM_HPP_INCLUDED_ | |
b32b8144 FG |
20 | |
21 | #include <boost/atomic/detail/config.hpp> | |
22 | #include <boost/atomic/detail/platform.hpp> | |
23 | ||
24 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
25 | #pragma once | |
26 | #endif | |
27 | ||
20effc67 TL |
28 | #if defined(__ARMEL__) || \ |
29 | (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ | |
30 | (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ | |
31 | defined(BOOST_WINDOWS) | |
32 | #define BOOST_ATOMIC_DETAIL_ARM_LITTLE_ENDIAN | |
33 | #elif defined(__ARMEB__) || \ | |
34 | defined(__ARM_BIG_ENDIAN) || \ | |
35 | (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ | |
36 | (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) | |
37 | #define BOOST_ATOMIC_DETAIL_ARM_BIG_ENDIAN | |
38 | #else | |
39 | #error "Boost.Atomic: Failed to determine ARM endianness, the target platform is not supported. Please, report to the developers (patches are welcome)." | |
40 | #endif | |
41 | ||
42 | #if defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH >= 6) | |
b32b8144 FG |
43 | |
44 | #if BOOST_ATOMIC_DETAIL_ARM_ARCH > 6 | |
45 | // ARMv7 and later have dmb instruction | |
46 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_DMB 1 | |
47 | #endif | |
48 | ||
49 | #if defined(__ARM_FEATURE_LDREX) | |
50 | ||
51 | #if (__ARM_FEATURE_LDREX & 1) | |
52 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1 | |
53 | #endif | |
54 | #if (__ARM_FEATURE_LDREX & 2) | |
55 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1 | |
56 | #endif | |
57 | #if (__ARM_FEATURE_LDREX & 8) | |
58 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1 | |
59 | #endif | |
60 | ||
61 | #else // defined(__ARM_FEATURE_LDREX) | |
62 | ||
63 | #if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)) | |
64 | ||
65 | // ARMv6k and ARMv7 have 8 and 16-bit ldrex/strex variants, but at least GCC 4.7 fails to compile them. GCC 4.9 is known to work. | |
66 | #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 | |
67 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1 | |
68 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1 | |
69 | #endif | |
70 | ||
71 | #if !(((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7M__)) | |
72 | // ARMv6k and ARMv7 except ARMv7-M have 64-bit ldrex/strex variants. | |
73 | // Unfortunately, GCC (at least 4.7.3 on Ubuntu) does not allocate register pairs properly when targeting ARMv6k Thumb, | |
74 | // which is required for ldrexd/strexd instructions, so we disable 64-bit support. When targeting ARMv6k ARM | |
75 | // or ARMv7 (both ARM and Thumb 2) it works as expected. | |
76 | #define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1 | |
77 | #endif | |
78 | ||
79 | #endif // !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)) | |
80 | ||
81 | #endif // defined(__ARM_FEATURE_LDREX) | |
82 | ||
20effc67 TL |
83 | #endif // defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH >= 6) |
84 | ||
85 | #define BOOST_ATOMIC_INT8_LOCK_FREE 2 | |
86 | #define BOOST_ATOMIC_INT16_LOCK_FREE 2 | |
87 | #define BOOST_ATOMIC_INT32_LOCK_FREE 2 | |
88 | #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) | |
89 | #define BOOST_ATOMIC_INT64_LOCK_FREE 2 | |
90 | #endif | |
91 | #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 | |
92 | ||
93 | #define BOOST_ATOMIC_THREAD_FENCE 2 | |
94 | #define BOOST_ATOMIC_SIGNAL_FENCE 2 | |
b32b8144 | 95 | |
20effc67 | 96 | #endif // BOOST_ATOMIC_DETAIL_CAPS_ARCH_GCC_ARM_HPP_INCLUDED_ |