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.
test_arch_subset(Arch current,Arch required)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