Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
x86_x64.h
Go to the documentation of this file.
1/* Copyright (C) 2022 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#if !ARCH_X86_X64
31#error "including x86_x64.h without ARCH_X86_X64=1"
32#endif
33
34#if MSC_VERSION
35#include <intrin.h> // __rdtsc
36#endif
37
38namespace x86_x64 {
39
40/**
41 * registers used/returned by cpuid
42 **/
43#pragma pack(push, 1) // (allows casting to int*)
45{
50};
51#pragma pack(pop)
52
53/**
54 * invoke CPUID instruction.
55 * @param regs input/output registers.
56 * regs->eax must be set to the desired function.
57 * some functions (e.g. 4) require regs->ecx to be set as well.
58 * rationale: this interface (input/output structure vs. function parameters)
59 * avoids unnecessary copying/initialization if some inputs aren't needed
60 * and allows graceful expansion to functions that require further inputs.
61 * @return true on success or false if the sub-function isn't supported.
62 **/
63bool cpuid(CpuidRegs* regs);
64
65/**
66 * CPU vendor.
67 * (this is exposed because some CPUID functions are vendor-specific.)
68 * (an enum is easier to compare than the original string values.)
69 **/
71{
75};
76
78
79
81{
82 MODEL_NEHALEM_EP = 0x1A, // Bloomfield (X35xx), Gainestown (X55xx)
83 MODEL_NEHALEM_EP_2 = 0x1E, // Clarksfield, Lynnfield (X34xx), Jasper Forest (C35xx, C55xx)
84 MODEL_I7_I5 = 0x1F, // similar to 1E; mentioned in 253665-041US, no codename known
85 MODEL_CLARKDALE = 0x25, // Arrandale, Clarkdale (L34xx)
86 MODEL_WESTMERE_EP = 0x2C, // Gulftown (X36xx, X56xx)
87 MODEL_NEHALEM_EX = 0x2E, // Beckton (X75xx)
88 MODEL_WESTMERE_EX = 0x2F, // Gulftown uarch, Beckton package (E7-48xx)
89 MODEL_SANDY_BRIDGE = 0x2A, // (E3-12xx, E5-26xx)
90 MODEL_SANDY_BRIDGE_2 = 0x2D, // (E5-26xx, E5-46xx)
91};
92
93size_t Model();
94
95size_t Family();
96
97
98/**
99 * @return the colloquial processor generation
100 * (5 = Pentium, 6 = Pentium Pro/II/III / K6, 7 = Pentium4 / Athlon, 8 = Core / Opteron)
101 **/
102size_t Generation();
103
104
105/**
106 * bit indices of CPU capability flags (128 bits).
107 * values are defined by IA-32 CPUID feature flags - do not change!
108 **/
110{
111 // standard (ecx) - currently only defined by Intel
112 CAP_SSE3 = 0+0, // Streaming SIMD Extensions 3
113 CAP_EST = 0+7, // Enhanced Speedstep Technology
114 CAP_SSSE3 = 0+9, // Supplemental Streaming SIMD Extensions 3
115 CAP_SSE41 = 0+19, // Streaming SIMD Extensions 4.1
116 CAP_SSE42 = 0+20, // Streaming SIMD Extensions 4.2
117
118 // standard (edx)
119 CAP_FPU = 32+0, // Floating Point Unit
120 CAP_TSC = 32+4, // TimeStamp Counter
121 CAP_MSR = 32+5, // Model Specific Registers
122 CAP_CMOV = 32+15, // Conditional MOVe
123 CAP_TM_SCC = 32+22, // Thermal Monitoring and Software Controlled Clock
124 CAP_MMX = 32+23, // MultiMedia eXtensions
125 CAP_SSE = 32+25, // Streaming SIMD Extensions
126 CAP_SSE2 = 32+26, // Streaming SIMD Extensions 2
127 CAP_HT = 32+28, // HyperThreading
128
129 // extended (ecx)
130 CAP_AMD_CMP_LEGACY = 64+1, // N-core and CAP_HT is falsely set
131
132 // extended (edx)
133 CAP_AMD_MP = 96+19, // MultiProcessing capable; reserved on AMD64
136 CAP_AMD_3DNOW = 96+31
138
139/**
140 * @return whether the CPU supports the indicated Cap / feature flag.
141 **/
142bool Cap(Caps cap);
143
144void GetCapBits(u32* d0, u32* d1, u32* d2, u32* d3);
145
146
147//-----------------------------------------------------------------------------
148// stateless
149
150/**
151 * @return the current value of the TimeStampCounter (a counter of
152 * CPU cycles since power-on, which is useful for high-resolution timing
153 * but potentially differs between multiple CPUs)
154 *
155 * notes:
156 * - a macro avoids call overhead, which is important for TIMER_ACCRUE.
157 * - x64 RDTSC writes to edx:eax and clears the upper halves of rdx and rax.
158 **/
159#if MSC_VERSION
160static inline u64 rdtsc() { return __rdtsc(); }
161#else
162u64 rdtsc();
163#endif
164
165/**
166 * trigger a breakpoint inside this function when it is called.
167 **/
168void DebugBreak();
169
170/**
171 * measure the CPU clock frequency via rdtsc and timer_Time.
172 * (it follows that this must not be called from WHRT init.)
173 * this takes several milliseconds (i.e. much longer than
174 * os_cpu_ClockFrequency) but delivers accurate measurements.
175 **/
176double ClockFrequency();
177
178} // namespace x86_x64
179
180#endif // #ifndef INCLUDED_X86_X64
Definition: x86_x64.cpp:47
bool cpuid(CpuidRegs *regs)
invoke CPUID instruction.
Definition: x86_x64.cpp:98
void GetCapBits(u32 *d0, u32 *d1, u32 *d2, u32 *d3)
Definition: x86_x64.cpp:156
void DebugBreak()
trigger a breakpoint inside this function when it is called.
Definition: x86_x64.cpp:385
Vendors Vendor()
Definition: x86_x64.cpp:200
Models
Definition: x86_x64.h:81
@ MODEL_NEHALEM_EP_2
Definition: x86_x64.h:83
@ MODEL_NEHALEM_EX
Definition: x86_x64.h:87
@ MODEL_NEHALEM_EP
Definition: x86_x64.h:82
@ MODEL_SANDY_BRIDGE
Definition: x86_x64.h:89
@ MODEL_WESTMERE_EP
Definition: x86_x64.h:86
@ MODEL_I7_I5
Definition: x86_x64.h:84
@ MODEL_WESTMERE_EX
Definition: x86_x64.h:88
@ MODEL_CLARKDALE
Definition: x86_x64.h:85
@ MODEL_SANDY_BRIDGE_2
Definition: x86_x64.h:90
Vendors
CPU vendor.
Definition: x86_x64.h:71
@ VENDOR_AMD
Definition: x86_x64.h:74
@ VENDOR_UNKNOWN
Definition: x86_x64.h:72
@ VENDOR_INTEL
Definition: x86_x64.h:73
double ClockFrequency()
measure the CPU clock frequency via rdtsc and timer_Time.
Definition: x86_x64.cpp:429
bool Cap(Caps cap)
Definition: x86_x64.cpp:142
size_t Model()
Definition: x86_x64.cpp:232
Caps
bit indices of CPU capability flags (128 bits).
Definition: x86_x64.h:110
@ CAP_AMD_MMX_EXT
Definition: x86_x64.h:134
@ CAP_TM_SCC
Definition: x86_x64.h:123
@ CAP_TSC
Definition: x86_x64.h:120
@ CAP_AMD_3DNOW_PRO
Definition: x86_x64.h:135
@ CAP_MMX
Definition: x86_x64.h:124
@ CAP_AMD_3DNOW
Definition: x86_x64.h:136
@ CAP_SSE42
Definition: x86_x64.h:116
@ CAP_EST
Definition: x86_x64.h:113
@ CAP_AMD_MP
Definition: x86_x64.h:133
@ CAP_CMOV
Definition: x86_x64.h:122
@ CAP_HT
Definition: x86_x64.h:127
@ CAP_FPU
Definition: x86_x64.h:119
@ CAP_SSE2
Definition: x86_x64.h:126
@ CAP_SSSE3
Definition: x86_x64.h:114
@ CAP_SSE
Definition: x86_x64.h:125
@ CAP_AMD_CMP_LEGACY
Definition: x86_x64.h:130
@ CAP_MSR
Definition: x86_x64.h:121
@ CAP_SSE3
Definition: x86_x64.h:112
@ CAP_SSE41
Definition: x86_x64.h:115
size_t Generation()
u64 rdtsc()
Definition: x86_x64.cpp:373
size_t Family()
Definition: x86_x64.cpp:238
registers used/returned by cpuid
Definition: x86_x64.h:45
u32 edx
Definition: x86_x64.h:49
u32 ecx
Definition: x86_x64.h:48
u32 eax
Definition: x86_x64.h:46
u32 ebx
Definition: x86_x64.h:47
uint64_t u64
Definition: types.h:40
uint32_t u32
Definition: types.h:39