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
13namespace 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*/
25enum 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
79inline 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
86inline 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
93inline 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
99inline 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
105inline 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.
112inline 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