1 | /* Copyright (C) 2013-2014 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_DISPATCH_ARCH_H |
9 | #define LIBSIMDPP_DISPATCH_ARCH_H |
10 | |
11 | #include <cstdint> |
12 | |
13 | namespace simdpp { |
14 | |
15 | /** Identifies supported instruction set. This type is a bitmask type |
16 | |
17 | Note: the exact values may change release to release. |
18 | */ |
19 | /* The values are assigned in such a way that the result of comparison of two |
20 | ORed flag sets is likely identify which instruction set the binary is more |
21 | likely to run faster on. |
22 | |
23 | detail::select_version depends on this. |
24 | */ |
25 | enum class Arch : std::uint32_t { |
26 | /// Indicates that no SIMD instructions are supported |
27 | NONE_NULL = 0, |
28 | /// Indicates x86 SSE2 support |
29 | X86_SSE2 = 1 << 1, |
30 | /// Indicates x86 SSE3 support |
31 | X86_SSE3 = 1 << 2, |
32 | /// Indicates x86 SSSE3 support |
33 | X86_SSSE3 = 1 << 3, |
34 | /// Indicates x86 SSE4.1 support |
35 | X86_SSE4_1 = 1 << 4, |
36 | /// Indicates x86 popcnt instruction support (Note: this is not equivalent |
37 | /// to the ABM CPUID flag, Intel includes the instruction into SSE 4.2) |
38 | X86_POPCNT_INSN = 1 << 5, |
39 | /// Indicates x86 AVX support |
40 | X86_AVX = 1 << 6, |
41 | /// Indicates x86 AVX2 support |
42 | X86_AVX2 = 1 << 7, |
43 | /// Indicates x86 FMA3 (Intel) support |
44 | X86_FMA3 = 1 << 8, |
45 | /// Indicates x86 FMA4 (AMD) support |
46 | X86_FMA4 = 1 << 9, |
47 | /// Indicates x86 XOP (AMD) support |
48 | X86_XOP = 1 << 10, |
49 | /// Indicates x86 AVX-512F suppotr |
50 | X86_AVX512F = 1 << 11, |
51 | /// Indicates x86 AVX-512BW suppotr |
52 | X86_AVX512BW = 1 << 12, |
53 | /// Indicates x86 AVX-512DQ suppotr |
54 | X86_AVX512DQ = 1 << 13, |
55 | /// Indicates x86 AVX-512VL suppotr |
56 | X86_AVX512VL = 1 << 14, |
57 | |
58 | /// Indicates ARM NEON support (SP and DP floating-point math is executed |
59 | /// on VFP) |
60 | ARM_NEON = 1 << 0, |
61 | /// Indicates ARM NEON support (SP floating-point math is executed on NEON, |
62 | /// DP floating-point math is executed on VFP) |
63 | ARM_NEON_FLT_SP = 1 << 1, |
64 | |
65 | /// Indicates POWER ALTIVEC support. |
66 | POWER_ALTIVEC = 1 << 0, |
67 | |
68 | /// Indicates POWER VSX support available since Power ISA 2.06 |
69 | POWER_VSX_206 = 1 << 1, |
70 | |
71 | /// Indicates POWER VSX support available since Power ISA 2.07 |
72 | POWER_VSX_207 = 1 << 2, |
73 | |
74 | /// Indicates MIPS MSA support |
75 | MIPS_MSA = 1 << 0 |
76 | }; |
77 | |
78 | /// Bitwise operators for @c Arch |
79 | inline Arch& operator|=(Arch& x, const Arch& y) |
80 | { |
81 | using T = std::uint32_t; |
82 | x = static_cast<Arch>(static_cast<T>(x) | static_cast<T>(y)); |
83 | return x; |
84 | } |
85 | |
86 | inline Arch& operator&=(Arch& x, const Arch& y) |
87 | { |
88 | using T = std::uint32_t; |
89 | x = static_cast<Arch>(static_cast<T>(x) & static_cast<T>(y)); |
90 | return x; |
91 | } |
92 | |
93 | inline Arch operator|(const Arch& x, const Arch& y) |
94 | { |
95 | using T = std::uint32_t; |
96 | return static_cast<Arch>(static_cast<T>(x) | static_cast<T>(y)); |
97 | } |
98 | |
99 | inline Arch operator&(const Arch& x, const Arch& y) |
100 | { |
101 | using T = std::uint32_t; |
102 | return static_cast<Arch>(static_cast<T>(x) & static_cast<T>(y)); |
103 | } |
104 | |
105 | inline Arch operator~(const Arch& x) |
106 | { |
107 | using T = std::uint32_t; |
108 | return static_cast<Arch>(~static_cast<T>(x)); |
109 | } |
110 | |
111 | /// Checks if the bits set in @a required is a subset of bits set in @a current. |
112 | inline bool test_arch_subset(Arch current, Arch required) |
113 | { |
114 | if ((~current & required) == Arch::NONE_NULL) { |
115 | return true; |
116 | } |
117 | return false; |
118 | } |
119 | |
120 | } // namespace simdpp |
121 | |
122 | #endif |
123 | |