llvm.org GIT mirror llvm / 3d6e973
[cpu-detection] Naming convention Summary: Follow-up to D20926 (committed as r271595, r271596). This patch is in preparation for a substantial refactoring of the code. No functionality changed. Differential Revision: http://reviews.llvm.org/D20970 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271726 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 4 years ago
1 changed file(s) with 27 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
7272 defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
7373 defined(_M_X64)
7474
75 /// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
75 /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
7676 /// the specified arguments. If we can't run cpuid on the host, return true.
77 static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
77 static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
7878 unsigned *rECX, unsigned *rEDX) {
7979 #if defined(__GNUC__) || defined(__clang__)
8080 #if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
111111 #endif
112112 }
113113
114 /// GetX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
115 /// the
116 /// 4 values in the specified arguments. If we can't run cpuid on the host,
114 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
115 /// the 4 values in the specified arguments. If we can't run cpuid on the host,
117116 /// return true.
118 static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
117 static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
119118 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
120119 unsigned *rEDX) {
121120 #if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
169168 #endif
170169 }
171170
172 static bool GetX86XCR0(unsigned *rEAX, unsigned *rEDX) {
171 static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
173172 #if defined(__GNUC__)
174173 // Check xgetbv; this uses a .byte sequence instead of the instruction
175174 // directly because older assemblers do not include support for xgetbv and
186185 #endif
187186 }
188187
189 static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
190 unsigned &Model) {
191 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
192 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
193 if (Family == 6 || Family == 0xf) {
194 if (Family == 0xf)
188 static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
189 unsigned *Model) {
190 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
191 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
192 if (*Family == 6 || *Family == 0xf) {
193 if (*Family == 0xf)
195194 // Examine extended family ID if family ID is F.
196 Family += (EAX >> 20) & 0xff; // Bits 20 - 27
195 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
197196 // Examine extended model ID if family ID is 6 or F.
198 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
197 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
199198 }
200199 }
201200
202201 StringRef sys::getHostCPUName() {
203202 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
204 if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
203 if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
205204 return "generic";
206205 unsigned Family = 0;
207206 unsigned Model = 0;
208 DetectX86FamilyModel(EAX, Family, Model);
207 detectX86FamilyModel(EAX, &Family, &Model);
209208
210209 union {
211210 unsigned u[3];
213212 } text;
214213
215214 unsigned MaxLeaf;
216 GetX86CpuIDAndInfo(0, &MaxLeaf, text.u + 0, text.u + 2, text.u + 1);
215 getX86CpuIDAndInfo(0, &MaxLeaf, text.u + 0, text.u + 2, text.u + 1);
217216
218217 bool HasMMX = (EDX >> 23) & 1;
219218 bool HasSSE = (EDX >> 25) & 1;
227226 // indicates that the AVX registers will be saved and restored on context
228227 // switch, then we have full AVX support.
229228 const unsigned AVXBits = (1 << 27) | (1 << 28);
230 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !GetX86XCR0(&EAX, &EDX) &&
229 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
231230 ((EAX & 0x6) == 0x6);
232231 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
233232 bool HasLeaf7 =
234 MaxLeaf >= 0x7 && !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
233 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
235234 bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
236235 bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
237236 bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
238237
239 GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
238 getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
240239 bool Em64T = (EDX >> 29) & 0x1;
241240 bool HasTBM = (ECX >> 21) & 0x1;
242241
774773 char c[12];
775774 } text;
776775
777 if (GetX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
776 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
778777 MaxLevel < 1)
779778 return false;
780779
781 GetX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
780 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
782781
783782 Features["cmov"] = (EDX >> 15) & 1;
784783 Features["mmx"] = (EDX >> 23) & 1;
800799 // indicates that the AVX registers will be saved and restored on context
801800 // switch, then we have full AVX support.
802801 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
803 !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
802 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
804803 Features["avx"] = HasAVXSave;
805804 Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
806805 Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
812811 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
813812
814813 unsigned MaxExtLevel;
815 GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
814 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
816815
817816 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
818 !GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
817 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
819818 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
820819 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
821820 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
825824 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
826825
827826 bool HasLeaf7 =
828 MaxLevel >= 7 && !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
827 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
829828
830829 // AVX2 is only supported if we have the OS save support from AVX.
831830 Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
861860 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
862861
863862 bool HasLeafD = MaxLevel >= 0xd &&
864 !GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
863 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
865864
866865 // Only enable XSAVE if OS has enabled support for saving YMM state.
867866 Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);