Skip to content

Commit 28c87d8

Browse files
committed
instructionset: remove inline variable data by template for c++14
1 parent 896299b commit 28c87d8

File tree

1 file changed

+281
-74
lines changed

1 file changed

+281
-74
lines changed

include/proxsuite/helpers/instruction-set.hpp

Lines changed: 281 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -41,81 +41,11 @@ cpuidex(std::array<int, 4>& cpui, int level, int count)
4141
__cpuidex(cpui.data(), level, count);
4242
#endif
4343
}
44-
}
4544

46-
// Adapted from
47-
// https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
48-
struct InstructionSet
45+
template<typename T = void>
46+
struct InstructionSetBase
4947
{
50-
static std::string vendor(void) { return data.vendor_; }
51-
static std::string brand(void) { return data.brand_; }
52-
53-
static bool has_SSE3(void) { return data.f_1_ECX_[0]; }
54-
static bool has_PCLMULQDQ(void) { return data.f_1_ECX_[1]; }
55-
static bool has_MONITOR(void) { return data.f_1_ECX_[3]; }
56-
static bool has_SSSE3(void) { return data.f_1_ECX_[9]; }
57-
static bool has_FMA(void) { return data.f_1_ECX_[12]; }
58-
static bool has_CMPXCHG16B(void) { return data.f_1_ECX_[13]; }
59-
static bool has_SSE41(void) { return data.f_1_ECX_[19]; }
60-
static bool has_SSE42(void) { return data.f_1_ECX_[20]; }
61-
static bool has_MOVBE(void) { return data.f_1_ECX_[22]; }
62-
static bool has_POPCNT(void) { return data.f_1_ECX_[23]; }
63-
static bool has_AES(void) { return data.f_1_ECX_[25]; }
64-
static bool has_XSAVE(void) { return data.f_1_ECX_[26]; }
65-
static bool has_OSXSAVE(void) { return data.f_1_ECX_[27]; }
66-
static bool has_AVX(void) { return data.f_1_ECX_[28]; }
67-
static bool has_F16C(void) { return data.f_1_ECX_[29]; }
68-
static bool has_RDRAND(void) { return data.f_1_ECX_[30]; }
69-
70-
static bool has_MSR(void) { return data.f_1_EDX_[5]; }
71-
static bool has_CX8(void) { return data.f_1_EDX_[8]; }
72-
static bool has_SEP(void) { return data.f_1_EDX_[11]; }
73-
static bool has_CMOV(void) { return data.f_1_EDX_[15]; }
74-
static bool has_CLFSH(void) { return data.f_1_EDX_[19]; }
75-
static bool has_MMX(void) { return data.f_1_EDX_[23]; }
76-
static bool has_FXSR(void) { return data.f_1_EDX_[24]; }
77-
static bool has_SSE(void) { return data.f_1_EDX_[25]; }
78-
static bool has_SSE2(void) { return data.f_1_EDX_[26]; }
79-
80-
static bool has_FSGSBASE(void) { return data.f_7_EBX_[0]; }
81-
static bool has_AVX512VBMI(void) { return data.f_7_EBX_[1]; }
82-
static bool has_BMI1(void) { return data.f_7_EBX_[3]; }
83-
static bool has_HLE(void) { return data.isIntel_ && data.f_7_EBX_[4]; }
84-
static bool has_AVX2(void) { return data.f_7_EBX_[5]; }
85-
static bool has_BMI2(void) { return data.f_7_EBX_[8]; }
86-
static bool has_ERMS(void) { return data.f_7_EBX_[9]; }
87-
static bool has_INVPCID(void) { return data.f_7_EBX_[10]; }
88-
static bool has_RTM(void) { return data.isIntel_ && data.f_7_EBX_[11]; }
89-
static bool has_AVX512F(void) { return data.f_7_EBX_[16]; }
90-
static bool has_AVX512DQ(void) { return data.f_7_EBX_[17]; }
91-
static bool has_RDSEED(void) { return data.f_7_EBX_[18]; }
92-
static bool has_ADX(void) { return data.f_7_EBX_[19]; }
93-
static bool has_AVX512IFMA(void) { return data.f_7_EBX_[21]; }
94-
static bool has_AVX512PF(void) { return data.f_7_EBX_[26]; }
95-
static bool has_AVX512ER(void) { return data.f_7_EBX_[27]; }
96-
static bool has_AVX512CD(void) { return data.f_7_EBX_[28]; }
97-
static bool has_SHA(void) { return data.f_7_EBX_[29]; }
98-
static bool has_AVX512BW(void) { return data.f_7_EBX_[30]; }
99-
static bool has_AVX512VL(void) { return data.f_7_EBX_[31]; }
100-
101-
static bool has_PREFETCHWT1(void) { return data.f_7_ECX_[0]; }
102-
103-
static bool has_LAHF(void) { return data.f_81_ECX_[0]; }
104-
static bool has_LZCNT(void) { return data.isIntel_ && data.f_81_ECX_[5]; }
105-
static bool has_ABM(void) { return data.isAMD_ && data.f_81_ECX_[5]; }
106-
static bool has_SSE4a(void) { return data.isAMD_ && data.f_81_ECX_[6]; }
107-
static bool has_XOP(void) { return data.isAMD_ && data.f_81_ECX_[11]; }
108-
static bool has_FMA4(void) { return data.isAMD_ && data.f_81_ECX_[16]; }
109-
static bool has_TBM(void) { return data.isAMD_ && data.f_81_ECX_[21]; }
110-
111-
static bool has_SYSCALL(void) { return data.isIntel_ && data.f_81_EDX_[11]; }
112-
static bool has_MMXEXT(void) { return data.isAMD_ && data.f_81_EDX_[22]; }
113-
static bool has_RDTSCP(void) { return data.isIntel_ && data.f_81_EDX_[27]; }
114-
static bool has_x64(void) { return data.isIntel_ && data.f_81_EDX_[29]; }
115-
static bool has_3DNOWEXT(void) { return data.isAMD_ && data.f_81_EDX_[30]; }
116-
static bool has_3DNOW(void) { return data.isAMD_ && data.f_81_EDX_[31]; }
117-
118-
private:
48+
protected:
11949
struct Data
12050
{
12151
Data()
@@ -214,7 +144,284 @@ struct InstructionSet
214144
std::vector<std::array<int, 4>> extdata_;
215145
};
216146

217-
inline static const Data data = Data();
147+
static const Data data;
148+
};
149+
150+
template<>
151+
const typename InstructionSetBase<>::Data InstructionSetBase<>::data =
152+
typename InstructionSetBase<>::Data();
153+
} // namespace internal
154+
155+
// Adapted from
156+
// https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
157+
// template <typename T>
158+
// struct InstructionSet: public internal::InstructionSetBase<T>
159+
struct InstructionSet : public internal::InstructionSetBase<>
160+
{
161+
static std::string vendor(void)
162+
{
163+
return internal::InstructionSetBase<>::data.vendor_;
164+
}
165+
static std::string brand(void)
166+
{
167+
return internal::InstructionSetBase<>::data.brand_;
168+
}
169+
170+
static bool has_SSE3(void)
171+
{
172+
return internal::InstructionSetBase<>::data.f_1_ECX_[0];
173+
}
174+
static bool has_PCLMULQDQ(void)
175+
{
176+
return internal::InstructionSetBase<>::data.f_1_ECX_[1];
177+
}
178+
static bool has_MONITOR(void)
179+
{
180+
return internal::InstructionSetBase<>::data.f_1_ECX_[3];
181+
}
182+
static bool has_SSSE3(void)
183+
{
184+
return internal::InstructionSetBase<>::data.f_1_ECX_[9];
185+
}
186+
static bool has_FMA(void)
187+
{
188+
return internal::InstructionSetBase<>::data.f_1_ECX_[12];
189+
}
190+
static bool has_CMPXCHG16B(void)
191+
{
192+
return internal::InstructionSetBase<>::data.f_1_ECX_[13];
193+
}
194+
static bool has_SSE41(void)
195+
{
196+
return internal::InstructionSetBase<>::data.f_1_ECX_[19];
197+
}
198+
static bool has_SSE42(void)
199+
{
200+
return internal::InstructionSetBase<>::data.f_1_ECX_[20];
201+
}
202+
static bool has_MOVBE(void)
203+
{
204+
return internal::InstructionSetBase<>::data.f_1_ECX_[22];
205+
}
206+
static bool has_POPCNT(void)
207+
{
208+
return internal::InstructionSetBase<>::data.f_1_ECX_[23];
209+
}
210+
static bool has_AES(void)
211+
{
212+
return internal::InstructionSetBase<>::data.f_1_ECX_[25];
213+
}
214+
static bool has_XSAVE(void)
215+
{
216+
return internal::InstructionSetBase<>::data.f_1_ECX_[26];
217+
}
218+
static bool has_OSXSAVE(void)
219+
{
220+
return internal::InstructionSetBase<>::data.f_1_ECX_[27];
221+
}
222+
static bool has_AVX(void)
223+
{
224+
return internal::InstructionSetBase<>::data.f_1_ECX_[28];
225+
}
226+
static bool has_F16C(void)
227+
{
228+
return internal::InstructionSetBase<>::data.f_1_ECX_[29];
229+
}
230+
static bool has_RDRAND(void)
231+
{
232+
return internal::InstructionSetBase<>::data.f_1_ECX_[30];
233+
}
234+
235+
static bool has_MSR(void)
236+
{
237+
return internal::InstructionSetBase<>::data.f_1_EDX_[5];
238+
}
239+
static bool has_CX8(void)
240+
{
241+
return internal::InstructionSetBase<>::data.f_1_EDX_[8];
242+
}
243+
static bool has_SEP(void)
244+
{
245+
return internal::InstructionSetBase<>::data.f_1_EDX_[11];
246+
}
247+
static bool has_CMOV(void)
248+
{
249+
return internal::InstructionSetBase<>::data.f_1_EDX_[15];
250+
}
251+
static bool has_CLFSH(void)
252+
{
253+
return internal::InstructionSetBase<>::data.f_1_EDX_[19];
254+
}
255+
static bool has_MMX(void)
256+
{
257+
return internal::InstructionSetBase<>::data.f_1_EDX_[23];
258+
}
259+
static bool has_FXSR(void)
260+
{
261+
return internal::InstructionSetBase<>::data.f_1_EDX_[24];
262+
}
263+
static bool has_SSE(void)
264+
{
265+
return internal::InstructionSetBase<>::data.f_1_EDX_[25];
266+
}
267+
static bool has_SSE2(void)
268+
{
269+
return internal::InstructionSetBase<>::data.f_1_EDX_[26];
270+
}
271+
272+
static bool has_FSGSBASE(void)
273+
{
274+
return internal::InstructionSetBase<>::data.f_7_EBX_[0];
275+
}
276+
static bool has_AVX512VBMI(void)
277+
{
278+
return internal::InstructionSetBase<>::data.f_7_EBX_[1];
279+
}
280+
static bool has_BMI1(void)
281+
{
282+
return internal::InstructionSetBase<>::data.f_7_EBX_[3];
283+
}
284+
static bool has_HLE(void)
285+
{
286+
return internal::InstructionSetBase<>::data.isIntel_ &&
287+
internal::InstructionSetBase<>::data.f_7_EBX_[4];
288+
}
289+
static bool has_AVX2(void)
290+
{
291+
return internal::InstructionSetBase<>::data.f_7_EBX_[5];
292+
}
293+
static bool has_BMI2(void)
294+
{
295+
return internal::InstructionSetBase<>::data.f_7_EBX_[8];
296+
}
297+
static bool has_ERMS(void)
298+
{
299+
return internal::InstructionSetBase<>::data.f_7_EBX_[9];
300+
}
301+
static bool has_INVPCID(void)
302+
{
303+
return internal::InstructionSetBase<>::data.f_7_EBX_[10];
304+
}
305+
static bool has_RTM(void)
306+
{
307+
return internal::InstructionSetBase<>::data.isIntel_ &&
308+
internal::InstructionSetBase<>::data.f_7_EBX_[11];
309+
}
310+
static bool has_AVX512F(void)
311+
{
312+
return internal::InstructionSetBase<>::data.f_7_EBX_[16];
313+
}
314+
static bool has_AVX512DQ(void)
315+
{
316+
return internal::InstructionSetBase<>::data.f_7_EBX_[17];
317+
}
318+
static bool has_RDSEED(void)
319+
{
320+
return internal::InstructionSetBase<>::data.f_7_EBX_[18];
321+
}
322+
static bool has_ADX(void)
323+
{
324+
return internal::InstructionSetBase<>::data.f_7_EBX_[19];
325+
}
326+
static bool has_AVX512IFMA(void)
327+
{
328+
return internal::InstructionSetBase<>::data.f_7_EBX_[21];
329+
}
330+
static bool has_AVX512PF(void)
331+
{
332+
return internal::InstructionSetBase<>::data.f_7_EBX_[26];
333+
}
334+
static bool has_AVX512ER(void)
335+
{
336+
return internal::InstructionSetBase<>::data.f_7_EBX_[27];
337+
}
338+
static bool has_AVX512CD(void)
339+
{
340+
return internal::InstructionSetBase<>::data.f_7_EBX_[28];
341+
}
342+
static bool has_SHA(void)
343+
{
344+
return internal::InstructionSetBase<>::data.f_7_EBX_[29];
345+
}
346+
static bool has_AVX512BW(void)
347+
{
348+
return internal::InstructionSetBase<>::data.f_7_EBX_[30];
349+
}
350+
static bool has_AVX512VL(void)
351+
{
352+
return internal::InstructionSetBase<>::data.f_7_EBX_[31];
353+
}
354+
355+
static bool has_PREFETCHWT1(void)
356+
{
357+
return internal::InstructionSetBase<>::data.f_7_ECX_[0];
358+
}
359+
360+
static bool has_LAHF(void)
361+
{
362+
return internal::InstructionSetBase<>::data.f_81_ECX_[0];
363+
}
364+
static bool has_LZCNT(void)
365+
{
366+
return internal::InstructionSetBase<>::data.isIntel_ &&
367+
internal::InstructionSetBase<>::data.f_81_ECX_[5];
368+
}
369+
static bool has_ABM(void)
370+
{
371+
return internal::InstructionSetBase<>::data.isAMD_ &&
372+
internal::InstructionSetBase<>::data.f_81_ECX_[5];
373+
}
374+
static bool has_SSE4a(void)
375+
{
376+
return internal::InstructionSetBase<>::data.isAMD_ &&
377+
internal::InstructionSetBase<>::data.f_81_ECX_[6];
378+
}
379+
static bool has_XOP(void)
380+
{
381+
return internal::InstructionSetBase<>::data.isAMD_ &&
382+
internal::InstructionSetBase<>::data.f_81_ECX_[11];
383+
}
384+
static bool has_FMA4(void)
385+
{
386+
return internal::InstructionSetBase<>::data.isAMD_ &&
387+
internal::InstructionSetBase<>::data.f_81_ECX_[16];
388+
}
389+
static bool has_TBM(void)
390+
{
391+
return internal::InstructionSetBase<>::data.isAMD_ &&
392+
internal::InstructionSetBase<>::data.f_81_ECX_[21];
393+
}
394+
395+
static bool has_SYSCALL(void)
396+
{
397+
return internal::InstructionSetBase<>::data.isIntel_ &&
398+
internal::InstructionSetBase<>::data.f_81_EDX_[11];
399+
}
400+
static bool has_MMXEXT(void)
401+
{
402+
return internal::InstructionSetBase<>::data.isAMD_ &&
403+
internal::InstructionSetBase<>::data.f_81_EDX_[22];
404+
}
405+
static bool has_RDTSCP(void)
406+
{
407+
return internal::InstructionSetBase<>::data.isIntel_ &&
408+
internal::InstructionSetBase<>::data.f_81_EDX_[27];
409+
}
410+
static bool has_x64(void)
411+
{
412+
return internal::InstructionSetBase<>::data.isIntel_ &&
413+
internal::InstructionSetBase<>::data.f_81_EDX_[29];
414+
}
415+
static bool has_3DNOWEXT(void)
416+
{
417+
return internal::InstructionSetBase<>::data.isAMD_ &&
418+
internal::InstructionSetBase<>::data.f_81_EDX_[30];
419+
}
420+
static bool has_3DNOW(void)
421+
{
422+
return internal::InstructionSetBase<>::data.isAMD_ &&
423+
internal::InstructionSetBase<>::data.f_81_EDX_[31];
424+
}
218425
};
219426

220427
} // helpers

0 commit comments

Comments
 (0)