source: trunk/lib/x86_CPU_detect.h @ 394

Last change on this file since 394 was 394, checked in by cameron, 9 years ago

Processor detection - initial check-in.

File size: 3.5 KB
Line 
1/*  x86_CPU_detect.h:  Run-Time Detection of x86 and x86_64 SIMD features.
2 
3    Copyright (C) 2010, Robert D. Cameron
4    Licensed to the public under Academic Free License version 3.0.
5
6This file defines the following functions which perform
7runtime tests to see if particular SIMD or other acceleration
8features are supported.   The functions return 0 if
9a feature is not supported, a nonzero value, otherwise.
10
11CPU_has_MMX()
12CPU_has_SSE()
13CPU_has_SSE2()
14CPU_has_SSE3()
15CPU_has_SSSE3()
16CPU_has_SSE41()
17CPU_has_SSE42()
18CPU_has_AVX()
19CPU_has_POPCOUNT()
20
21The CPUID instruction is used to determine these features,
22taking advantage of the appropriate __cpuid compiler intrinsic
23available with GCC and MSVC compilers.
24
25*/
26
27#ifndef X86_CPU_DETECT_H
28#define X86_CPU_DETECT_H
29
30enum CPUid_reg {
31  reg_eax = 0, 
32  reg_ebx = 1, 
33  reg_ecx = 2, 
34  reg_edx = 3
35};
36
37
38#define MMX_CPUid_feature_register reg_edx
39#define MMX_CPUid_feature_bit (1 << 23)
40
41#define SSE_CPUid_feature_register reg_edx
42#define SSE_CPUid_feature_bit (1 << 25)
43
44#define SSE2_CPUid_feature_register reg_edx
45#define SSE2_CPUid_feature_bit (1 << 26)
46
47#define SSE3_CPUid_feature_register reg_ecx
48#define SSE3_CPUid_feature_bit (1 << 0)
49
50#define SSSE3_CPUid_feature_register reg_ecx
51#define SSSE3_CPUid_feature_bit (1 << 9)
52
53#define SSE41_CPUid_feature_register reg_ecx
54#define SSE41_CPUid_feature_bit (1 << 19)
55
56#define SSE42_CPUid_feature_register reg_ecx
57#define SSE42_CPUid_feature_bit (1 << 20)
58
59#define AVX_CPUid_feature_register reg_ecx
60#define AVX_CPUid_feature_bit (1 << 28)
61
62#define POPCOUNT_CPUid_feature_register reg_ecx
63#define POPCOUNT_CPUid_feature_bit (1 << 23)
64
65
66#ifdef _MSC_VER
67#include <intrin.h>
68static inline int check_CPUid1_feature(CPUid_reg reg, int CPUid_bit) {
69  int CPUinfo[4];
70  __cpuid(CPUinfo, 1);
71  return CPUInfo[reg] & CPUid_bit;
72}
73#ifdef _M_X64
74#define x86_64 1
75#endif
76#endif
77
78#ifdef __GNUC__
79#include <cpuid.h>
80static inline int check_CPUid1_feature(CPUid_reg reg, int CPUid_bit) {
81  int CPUinfo[4];
82  if __get_cpuid(1, &CPUinfo[reg_eax], &CPUinfo[reg_ebx], &CPUinfo[reg_ecx], &CPUinfo[reg_edx]) {
83    return CPUInfo[reg] & CPUid_bit;
84  else return 0;
85}
86#ifdef __x86_64__
87#define x86_64 1
88#endif
89#endif
90
91static inline int CPU_has_MMX() {
92#ifdef x86_64
93  return MMX_CPUid_feature_bit;  /*  MMX always available on x86_64 */
94#else
95  return check_CPUid1_feature(MMX_CPUid_feature_register, MMX_CPUid_feature_bit);
96#endif
97}
98static inline int CPU_has_SSE() {
99#ifdef x86_64
100  return SSE_CPUid_feature_bit;  /*  SSE always available on x86_64 */
101#else
102  return check_CPUid1_feature(SSE_CPUid_feature_register, SSE_CPUid_feature_bit);
103#endif
104}
105static inline int CPU_has_SSE2() {
106#ifdef x86_64
107  return SSE2_CPUid_feature_bit;  /*  SSE2 always available on x86_64 */
108#else
109  return check_CPUid1_feature(SSE2_CPUid_feature_register, SSE2_CPUid_feature_bit);
110#endif
111}
112
113static inline int CPU_has_SSE3() {
114  return check_CPUid1_feature(SSE3_CPUid_feature_register, SSE3_CPUid_feature_bit);
115}
116
117static inline int CPU_has_SSSE3() {
118  return check_CPUid1_feature(SSSE3_CPUid_feature_register, SSSE3_CPUid_feature_bit);
119}
120
121static inline int CPU_has_SSE41() {
122  return check_CPUid1_feature(SSE41_CPUid_feature_register, SSE41_CPUid_feature_bit);
123}
124
125static inline int CPU_has_SSE42() {
126  return check_CPUid1_feature(SSE42_CPUid_feature_register, SSE42_CPUid_feature_bit);
127}
128
129static inline int CPU_has_AVX() {
130  return check_CPUid1_feature(AVX_CPUid_feature_register, AVX_CPUid_feature_bit);
131}
132
133static inline int CPU_has_POPCOUNT() {
134  return check_CPUid1_feature(POPCOUNT_CPUid_feature_register, POPCOUNT_CPUid_feature_bit);
135}
136
137#endif
138
Note: See TracBrowser for help on using the repository browser.