8#ifndef PROXSUITE_HELPERS_INSTRUCTION_SET_HPP
9#define PROXSUITE_HELPERS_INSTRUCTION_SET_HPP
26cpuid(std::array<int, 4>& cpui,
int level)
29 __cpuid(level, cpui[0], cpui[1], cpui[2], cpui[3]);
31 __cpuid(cpui.data(), level);
36cpuidex(std::array<int, 4>& cpui,
int level,
int count)
39 __cpuid_count(level, count, cpui[0], cpui[1], cpui[2], cpui[3]);
41 __cpuidex(cpui.data(), level, count);
45template<
typename T =
void>
46struct InstructionSetBase
65 std::array<int, 4> cpui;
66 typedef unsigned long long bistset_equivalent_type;
70 internal::cpuid(cpui, 0);
73 for (
int i = 0; i <= nIds_; ++i) {
74 internal::cpuidex(cpui, i, 0);
75 data_.push_back(cpui);
80 memset(vendor, 0,
sizeof(vendor));
81 *
reinterpret_cast<int*
>(vendor) = data_[0][1];
82 *
reinterpret_cast<int*
>(vendor + 4) = data_[0][3];
83 *
reinterpret_cast<int*
>(vendor + 8) = data_[0][2];
85 if (vendor_ ==
"GenuineIntel") {
87 }
else if (vendor_ ==
"AuthenticAMD") {
93 f_1_ECX_ =
static_cast<bistset_equivalent_type
>(data_[1][2]);
94 f_1_EDX_ =
static_cast<bistset_equivalent_type
>(data_[1][3]);
99 f_7_EBX_ =
static_cast<bistset_equivalent_type
>(data_[7][1]);
100 f_7_ECX_ =
static_cast<bistset_equivalent_type
>(data_[7][2]);
105 internal::cpuid(cpui,
static_cast<int>(0x80000000));
109 memset(brand, 0,
sizeof(brand));
111 for (
int i =
static_cast<int>(0x80000000); i <= nExIds_; ++i) {
112 internal::cpuidex(cpui, i, 0);
113 extdata_.push_back(cpui);
117 if (nExIds_ >=
static_cast<int>(0x80000001)) {
118 f_81_ECX_ =
static_cast<bistset_equivalent_type
>(extdata_[1][2]);
119 f_81_EDX_ =
static_cast<bistset_equivalent_type
>(extdata_[1][3]);
123 if (nExIds_ >=
static_cast<int>(0x80000004)) {
124 memcpy(brand, extdata_[2].data(),
sizeof(cpui));
125 memcpy(brand + 16, extdata_[3].data(),
sizeof(cpui));
126 memcpy(brand + 32, extdata_[4].data(),
sizeof(cpui));
137 std::bitset<32> f_1_ECX_;
138 std::bitset<32> f_1_EDX_;
139 std::bitset<32> f_7_EBX_;
140 std::bitset<32> f_7_ECX_;
141 std::bitset<32> f_81_ECX_;
142 std::bitset<32> f_81_EDX_;
143 std::vector<std::array<int, 4>> data_;
144 std::vector<std::array<int, 4>> extdata_;
147 static const Data data;
151const typename InstructionSetBase<>::Data InstructionSetBase<>::data =
152 typename InstructionSetBase<>::Data();
159 typedef internal::InstructionSetBase<>
Base;
161 static std::string
vendor(
void) {
return Base::data.vendor_; }
162 static std::string
brand(
void) {
return Base::data.brand_; }
164 static bool has_SSE3(
void) {
return Base::data.f_1_ECX_[0]; }
167 static bool has_SSSE3(
void) {
return Base::data.f_1_ECX_[9]; }
168 static bool has_FMA(
void) {
return Base::data.f_1_ECX_[12]; }
170 static bool has_SSE41(
void) {
return Base::data.f_1_ECX_[19]; }
171 static bool has_SSE42(
void) {
return Base::data.f_1_ECX_[20]; }
172 static bool has_MOVBE(
void) {
return Base::data.f_1_ECX_[22]; }
173 static bool has_POPCNT(
void) {
return Base::data.f_1_ECX_[23]; }
174 static bool has_AES(
void) {
return Base::data.f_1_ECX_[25]; }
175 static bool has_XSAVE(
void) {
return Base::data.f_1_ECX_[26]; }
177 static bool has_AVX(
void) {
return Base::data.f_1_ECX_[28]; }
178 static bool has_F16C(
void) {
return Base::data.f_1_ECX_[29]; }
179 static bool has_RDRAND(
void) {
return Base::data.f_1_ECX_[30]; }
181 static bool has_MSR(
void) {
return Base::data.f_1_EDX_[5]; }
182 static bool has_CX8(
void) {
return Base::data.f_1_EDX_[8]; }
183 static bool has_SEP(
void) {
return Base::data.f_1_EDX_[11]; }
184 static bool has_CMOV(
void) {
return Base::data.f_1_EDX_[15]; }
185 static bool has_CLFSH(
void) {
return Base::data.f_1_EDX_[19]; }
186 static bool has_MMX(
void) {
return Base::data.f_1_EDX_[23]; }
187 static bool has_FXSR(
void) {
return Base::data.f_1_EDX_[24]; }
188 static bool has_SSE(
void) {
return Base::data.f_1_EDX_[25]; }
189 static bool has_SSE2(
void) {
return Base::data.f_1_EDX_[26]; }
193 static bool has_BMI1(
void) {
return Base::data.f_7_EBX_[3]; }
196 return Base::data.isIntel_ && Base::data.f_7_EBX_[4];
198 static bool has_AVX2(
void) {
return Base::data.f_7_EBX_[5]; }
199 static bool has_BMI2(
void) {
return Base::data.f_7_EBX_[8]; }
200 static bool has_ERMS(
void) {
return Base::data.f_7_EBX_[9]; }
204 return Base::data.isIntel_ && Base::data.f_7_EBX_[11];
208 static bool has_RDSEED(
void) {
return Base::data.f_7_EBX_[18]; }
209 static bool has_ADX(
void) {
return Base::data.f_7_EBX_[19]; }
214 static bool has_SHA(
void) {
return Base::data.f_7_EBX_[29]; }
220 static bool has_LAHF(
void) {
return Base::data.f_81_ECX_[0]; }
223 return Base::data.isIntel_ && Base::data.f_81_ECX_[5];
227 return Base::data.isAMD_ && Base::data.f_81_ECX_[5];
231 return Base::data.isAMD_ && Base::data.f_81_ECX_[6];
235 return Base::data.isAMD_ && Base::data.f_81_ECX_[11];
239 return Base::data.isAMD_ && Base::data.f_81_ECX_[16];
243 return Base::data.isAMD_ && Base::data.f_81_ECX_[21];
248 return Base::data.isIntel_ && Base::data.f_81_EDX_[11];
252 return Base::data.isAMD_ && Base::data.f_81_EDX_[22];
256 return Base::data.isIntel_ && Base::data.f_81_EDX_[27];
260 return Base::data.isIntel_ && Base::data.f_81_EDX_[29];
264 return Base::data.isAMD_ && Base::data.f_81_EDX_[30];
268 return Base::data.isAMD_ && Base::data.f_81_EDX_[31];
static bool has_FMA(void)
static bool has_SSE3(void)
static bool has_ADX(void)
static bool has_MONITOR(void)
static bool has_MSR(void)
static bool has_XSAVE(void)
static bool has_AVX512VL(void)
static bool has_AVX512CD(void)
static bool has_MMXEXT(void)
static bool has_RDRAND(void)
static bool has_AVX512IFMA(void)
static bool has_BMI2(void)
static bool has_CMPXCHG16B(void)
static bool has_PREFETCHWT1(void)
static bool has_SSE(void)
static bool has_ERMS(void)
static bool has_AVX512ER(void)
static bool has_SSSE3(void)
static bool has_FSGSBASE(void)
static bool has_XOP(void)
static bool has_AVX512DQ(void)
static bool has_SSE4a(void)
static bool has_3DNOW(void)
static bool has_BMI1(void)
static bool has_SYSCALL(void)
static bool has_TBM(void)
static bool has_CMOV(void)
static bool has_AVX512BW(void)
static bool has_INVPCID(void)
static std::string vendor(void)
static bool has_SSE42(void)
static bool has_MMX(void)
static bool has_SEP(void)
static bool has_AES(void)
static bool has_RDSEED(void)
static bool has_LAHF(void)
static std::string brand(void)
static bool has_FXSR(void)
static bool has_CLFSH(void)
static bool has_AVX512PF(void)
static bool has_SSE41(void)
static bool has_LZCNT(void)
internal::InstructionSetBase Base
static bool has_CX8(void)
static bool has_AVX2(void)
static bool has_POPCNT(void)
static bool has_OSXSAVE(void)
static bool has_MOVBE(void)
static bool has_RDTSCP(void)
static bool has_AVX512F(void)
static bool has_HLE(void)
static bool has_F16C(void)
static bool has_AVX(void)
static bool has_AVX512VBMI(void)
static bool has_x64(void)
static bool has_3DNOWEXT(void)
static bool has_PCLMULQDQ(void)
static bool has_ABM(void)
static bool has_SHA(void)
static bool has_RTM(void)
static bool has_FMA4(void)
static bool has_SSE2(void)