Pyrogenesis  trunk
x86_x64.h
Go to the documentation of this file.
1 /* Copyright (c) 2010 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * CPU-specific routines common to 32 and 64-bit x86
25  */
26 
27 #ifndef INCLUDED_X86_X64
28 #define INCLUDED_X86_X64
29 
30 #include "lib/lib_api.h"
31 
32 #if !ARCH_X86_X64
33 #error "including x86_x64.h without ARCH_X86_X64=1"
34 #endif
35 
36 #if MSC_VERSION
37 #include <intrin.h> // __rdtsc
38 #endif
39 
40 namespace x86_x64 {
41 
42 /**
43  * registers used/returned by cpuid
44  **/
45 #pragma pack(push, 1) // (allows casting to int*)
46 struct CpuidRegs
47 {
52 };
53 #pragma pack(pop)
54 
55 /**
56  * invoke CPUID instruction.
57  * @param regs input/output registers.
58  * regs->eax must be set to the desired function.
59  * some functions (e.g. 4) require regs->ecx to be set as well.
60  * rationale: this interface (input/output structure vs. function parameters)
61  * avoids unnecessary copying/initialization if some inputs aren't needed
62  * and allows graceful expansion to functions that require further inputs.
63  * @return true on success or false if the sub-function isn't supported.
64  **/
65 LIB_API bool cpuid(CpuidRegs* regs);
66 
67 /**
68  * CPU vendor.
69  * (this is exposed because some CPUID functions are vendor-specific.)
70  * (an enum is easier to compare than the original string values.)
71  **/
72 enum Vendors
73 {
77 };
78 
79 LIB_API Vendors Vendor();
80 
81 
82 enum Models
83 {
84  MODEL_NEHALEM_EP = 0x1A, // Bloomfield (X35xx), Gainestown (X55xx)
85  MODEL_NEHALEM_EP_2 = 0x1E, // Clarksfield, Lynnfield (X34xx), Jasper Forest (C35xx, C55xx)
86  MODEL_I7_I5 = 0x1F, // similar to 1E; mentioned in 253665-041US, no codename known
87  MODEL_CLARKDALE = 0x25, // Arrandale, Clarkdale (L34xx)
88  MODEL_WESTMERE_EP = 0x2C, // Gulftown (X36xx, X56xx)
89  MODEL_NEHALEM_EX = 0x2E, // Beckton (X75xx)
90  MODEL_WESTMERE_EX = 0x2F, // Gulftown uarch, Beckton package (E7-48xx)
91  MODEL_SANDY_BRIDGE = 0x2A, // (E3-12xx, E5-26xx)
92  MODEL_SANDY_BRIDGE_2 = 0x2D, // (E5-26xx, E5-46xx)
93 };
94 
95 LIB_API size_t Model();
96 
97 LIB_API size_t Family();
98 
99 
100 /**
101  * @return the colloquial processor generation
102  * (5 = Pentium, 6 = Pentium Pro/II/III / K6, 7 = Pentium4 / Athlon, 8 = Core / Opteron)
103  **/
104 LIB_API size_t Generation();
105 
106 
107 /**
108  * bit indices of CPU capability flags (128 bits).
109  * values are defined by IA-32 CPUID feature flags - do not change!
110  **/
111 enum Caps
112 {
113  // standard (ecx) - currently only defined by Intel
114  CAP_SSE3 = 0+0, // Streaming SIMD Extensions 3
115  CAP_EST = 0+7, // Enhanced Speedstep Technology
116  CAP_SSSE3 = 0+9, // Supplemental Streaming SIMD Extensions 3
117  CAP_SSE41 = 0+19, // Streaming SIMD Extensions 4.1
118  CAP_SSE42 = 0+20, // Streaming SIMD Extensions 4.2
119 
120  // standard (edx)
121  CAP_FPU = 32+0, // Floating Point Unit
122  CAP_TSC = 32+4, // TimeStamp Counter
123  CAP_MSR = 32+5, // Model Specific Registers
124  CAP_CMOV = 32+15, // Conditional MOVe
125  CAP_TM_SCC = 32+22, // Thermal Monitoring and Software Controlled Clock
126  CAP_MMX = 32+23, // MultiMedia eXtensions
127  CAP_SSE = 32+25, // Streaming SIMD Extensions
128  CAP_SSE2 = 32+26, // Streaming SIMD Extensions 2
129  CAP_HT = 32+28, // HyperThreading
130 
131  // extended (ecx)
132  CAP_AMD_CMP_LEGACY = 64+1, // N-core and CAP_HT is falsely set
133 
134  // extended (edx)
135  CAP_AMD_MP = 96+19, // MultiProcessing capable; reserved on AMD64
139 };
140 
141 /**
142  * @return whether the CPU supports the indicated Cap / feature flag.
143  **/
144 LIB_API bool Cap(Caps cap);
145 
146 LIB_API void GetCapBits(u32* d0, u32* d1, u32* d2, u32* d3);
147 
148 
149 //-----------------------------------------------------------------------------
150 // stateless
151 
152 /**
153  * @return the current value of the TimeStampCounter (a counter of
154  * CPU cycles since power-on, which is useful for high-resolution timing
155  * but potentially differs between multiple CPUs)
156  *
157  * notes:
158  * - a macro avoids call overhead, which is important for TIMER_ACCRUE.
159  * - x64 RDTSC writes to edx:eax and clears the upper halves of rdx and rax.
160  **/
161 #if MSC_VERSION
162 static inline u64 rdtsc() { return __rdtsc(); }
163 #else
164 LIB_API u64 rdtsc();
165 #endif
166 
167 /**
168  * trigger a breakpoint inside this function when it is called.
169  **/
170 LIB_API void DebugBreak();
171 
172 /**
173  * measure the CPU clock frequency via rdtsc and timer_Time.
174  * (it follows that this must not be called from WHRT init.)
175  * this takes several milliseconds (i.e. much longer than
176  * os_cpu_ClockFrequency) but delivers accurate measurements.
177  **/
178 LIB_API double ClockFrequency();
179 
180 } // namespace x86_x64
181 
182 #endif // #ifndef INCLUDED_X86_X64
Definition: x86_x64.h:123
LIB_API size_t Generation()
u32 ecx
Definition: x86_x64.h:50
Definition: x86_x64.h:126
Definition: x86_x64.h:137
Definition: x86_x64.h:127
Definition: x86_x64.h:90
Definition: x86_x64.h:91
Definition: x86_x64.h:121
Vendors Vendor()
Definition: x86_x64.cpp:210
Definition: x86_x64.h:124
Definition: x86_x64.h:129
Definition: x86_x64.h:75
u32 edx
Definition: x86_x64.h:51
uint64_t u64
Definition: types.h:40
Definition: x86_x64.h:136
Definition: x86_x64.h:114
Definition: x86_x64.h:118
Definition: x86_x64.h:116
uint32_t u32
Definition: types.h:39
Definition: x86_x64.h:74
Definition: x86_x64.h:138
Models
Definition: x86_x64.h:82
bool cpuid(CpuidRegs *regs)
invoke CPUID instruction.
Definition: x86_x64.cpp:108
Caps
bit indices of CPU capability flags (128 bits).
Definition: x86_x64.h:111
u32 ebx
Definition: x86_x64.h:49
Definition: x86_x64.h:87
Definition: x86_x64.h:85
Definition: x86_x64.h:115
double ClockFrequency()
measure the CPU clock frequency via rdtsc and timer_Time.
Definition: x86_x64.cpp:439
void DebugBreak()
trigger a breakpoint inside this function when it is called.
Definition: x86_x64.cpp:395
Definition: x86_x64.h:122
void GetCapBits(u32 *d0, u32 *d1, u32 *d2, u32 *d3)
Definition: x86_x64.cpp:166
Definition: x86_x64.h:76
Definition: x86_x64.h:88
Definition: x86_x64.h:132
Definition: cache.cpp:32
Definition: x86_x64.h:89
bool Cap(Caps cap)
Definition: x86_x64.cpp:152
Definition: x86_x64.h:125
u32 eax
Definition: x86_x64.h:48
size_t Family()
Definition: x86_x64.cpp:248
Definition: x86_x64.h:128
registers used/returned by cpuid
Definition: x86_x64.h:46
Definition: x86_x64.h:92
Definition: x86_x64.h:135
u64 rdtsc()
Definition: x86_x64.cpp:383
Definition: x86_x64.h:84
Vendors
CPU vendor.
Definition: x86_x64.h:72
Definition: x86_x64.h:86
size_t Model()
Definition: x86_x64.cpp:242
Definition: x86_x64.h:117