2 * Identify the characteristics of the host CPU.
4 * Implemented according to:
6 - AP-485 Intel(C) Processor Identification and the CPUID Instruction
7 $(LINK http://www.intel.com/design/xeon/applnots/241618.htm)
9 - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 2A: Instruction Set Reference, A-M
10 $(LINK http://developer.intel.com/design/pentium4/manuals/index_new.htm)
12 - AMD CPUID Specification Publication # 25481
13 $(LINK http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf)
22 writefln(std.cpuid.toString());
26 AUTHORS: Tomas Lindquist Olsen <tomas@famolsen.dk>
27 (slightly altered by Walter Bright)
28 COPYRIGHT: Public Domain
30 * BUGS: Only works on x86 CPUs
33 * WIKI = Phobos/StdCpuid
34 * COPYRIGHT = Public Domain
38 * Modified by Sean Kelly for use with the D Runtime Project
43 private import stdc.string;
45 version(D_InlineAsm_X86)
47 /// Returns vendor string
48 char[] vendor() {return vendorStr;}
49 /// Returns processor string
50 string processor() {return processorStr;}
53 bool mmx() {return (flags&MMX_BIT)!=0;}
54 /// Is FXSR supported?
55 bool fxsr() {return (flags&FXSR_BIT)!=0;}
57 bool sse() {return (flags&SSE_BIT)!=0;}
58 /// Is SSE2 supported?
59 bool sse2() {return (flags&SSE2_BIT)!=0;}
60 /// Is SSE3 supported?
61 bool sse3() {return (misc&SSE3_BIT)!=0;}
62 /// Is SSSE3 supported?
63 bool ssse3() {return (misc&SSSE3_BIT)!=0;}
65 /// Is AMD 3DNOW supported?
66 bool amd3dnow() {return (exflags&AMD_3DNOW_BIT)!=0;}
67 /// Is AMD 3DNOW Ext supported?
68 bool amd3dnowExt() {return (exflags&AMD_3DNOW_EXT_BIT)!=0;}
69 /// Is AMD MMX supported?
70 bool amdMmx() {return (exflags&AMD_MMX_BIT)!=0;}
72 /// Is this an Intel Architecture IA64?
73 bool ia64() {return (flags&IA64_BIT)!=0;}
74 /// Is this an AMD 64?
75 bool amd64() {return (exflags&AMD64_BIT)!=0;}
77 /// Is hyperthreading supported?
78 bool hyperThreading() {return (flags&HTT_BIT)!=0;}
79 /// Returns number of threads per CPU
80 uint threadsPerCPU() {return maxThreads;}
81 /// Returns number of cores in CPU
82 uint coresPerCPU() {return maxCores;}
84 /// Is this an Intel processor?
85 bool intel() {return manufac==INTEL;}
86 /// Is this an AMD processor?
87 bool amd() {return manufac==AMD;}
90 uint stepping() {return _stepping;}
92 uint model() {return _model;}
94 uint family() {return _family;}
95 //uint processorType() {return (signature>>>12)&0x3;}
100 getProcessorString();
103 // stepping / family / model
104 _stepping = signature&0xF;
105 uint fbase = (signature>>>8)&0xF;
106 uint fex = (signature>>>20)&0xFF;
107 uint mbase = (signature>>>4)&0xF;
108 uint mex = (signature>>>16)&0xF;
111 void function() threadFn;
116 threadFn = &getThreadingIntel;
121 if (_family == 0x6 || _family == 0xF)
122 _model = mbase+(mex<<4);
129 threadFn = &getThreadingAMD;
138 _model = mbase+(mex<<4);
147 if (hyperThreading && threadFn !is null)
164 // feature flags misc
170 // extended feature flags
175 AMD_3DNOW_EXT_BIT = 1<<30,
176 AMD_3DNOW_BIT = 1<<31
186 uint flags, misc, exflags, apic, signature;
187 uint _stepping, _model, _family;
189 char[12] vendorStr = 0;
190 string processorStr = "";
197 * fetches the cpu vendor string
199 private void getVendorString()
201 char* dst = vendorStr.ptr;
202 // puts the vendor string into dst
214 private void getProcessorString()
217 char* dst = buffer.ptr;
218 // puts the processor string into dst
221 mov EAX, 0x8000_0000 ;
223 cmp EAX, 0x8000_0004 ;
224 jb PSLabel ; // no support
227 mov EAX, 0x8000_0002 ;
233 mov EAX, 0x8000_0003 ;
239 mov EAX, 0x8000_0004 ;
249 if (buffer[0] == char.init) // no support
252 // seems many intel processors prepend whitespace
253 processorStr = cast(string)strip(toString(dst)).dup;
256 private void getFeatureFlags()
264 jb FeatLabel ; // no support
273 mov EAX, 0x8000_0000 ;
275 cmp EAX, 0x8000_0001 ;
276 jb FeatLabel2 ; // no support
277 mov EAX, 0x8000_0001 ;
291 private void getThreadingIntel()
310 maxCores = ((n>>>26)&0x3F)+1;
311 maxThreads = (apic>>>16)&0xFF;
315 maxCores = maxThreads = 1;
319 private void getThreadingAMD()
325 mov EAX, 0x8000_0000 ;
327 cmp EAX, 0x8000_0008 ;
329 mov EAX, 0x8000_0008 ;
338 maxThreads = (apic>>>16)&0xFF;
342 maxCores = maxThreads = 1;
346 /***************************************************************************
347 * Support code for above, from std.string and std.ctype
348 ***************************************************************************/
367 _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
368 _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL,
369 _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
370 _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
371 _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
372 _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
373 _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
374 _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
375 _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
376 _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC,
377 _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
378 _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
379 _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC,
380 _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC,
381 _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
382 _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
383 _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL
387 * Returns !=0 if c is a space, tab, vertical tab, form feed,
388 * carriage return, or linefeed.
390 int isspace(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_SPC) : 0; }
392 /*****************************************
393 * Strips leading or trailing whitespace, or both.
395 char[] stripl(char[] s)
399 for (i = 0; i < s.length; i++)
404 return s[i .. s.length];
407 char[] stripr(char[] s) /// ditto
411 for (i = s.length; i > 0; i--)
413 if (!isspace(s[i - 1]))
419 char[] strip(char[] s) /// ditto
421 return stripr(stripl(s));
424 char[] toString(char* s)
426 return s ? s[0 .. strlen(s)] : null;
429 string toString(invariant(char)* s)
431 return s ? s[0 .. strlen(s)] : null;
437 char[] vendor() {return "unknown vendor"; }
438 char[] processor() {return "unknown processor"; }
440 bool mmx() {return false; }
441 bool fxsr() {return false; }
442 bool sse() {return false; }
443 bool sse2() {return false; }
444 bool sse3() {return false; }
445 bool ssse3() {return false; }
447 bool amd3dnow() {return false; }
448 bool amd3dnowExt() {return false; }
449 bool amdMmx() {return false; }
451 bool ia64() {return false; }
452 bool amd64() {return false; }
454 bool hyperThreading() {return false; }
455 uint threadsPerCPU() {return 0; }
456 uint coresPerCPU() {return 0; }
458 bool intel() {return false; }
459 bool amd() {return false; }
461 uint stepping() {return 0; }
462 uint model() {return 0; }
463 uint family() {return 0; }