PostgreSQL Source Code
git master
Loading...
Searching...
No Matches
pg_cpu_x86.c
Go to the documentation of this file.
1
/*-------------------------------------------------------------------------
2
*
3
* pg_cpu_x86.c
4
* Runtime CPU feature detection for x86
5
*
6
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
8
*
9
*
10
* IDENTIFICATION
11
* src/port/pg_cpu_x86.c
12
*
13
*-------------------------------------------------------------------------
14
*/
15
16
#include "
c.h
"
17
18
#if defined(USE_SSE2) || defined(__i386__)
19
20
#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
21
#include <cpuid.h>
22
#endif
23
24
#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
25
#include <intrin.h>
26
#endif
27
28
#ifdef HAVE_XSAVE_INTRINSICS
29
#include <immintrin.h>
30
#endif
31
32
#include "
port/pg_cpu.h
"
33
34
/*
35
* XSAVE state component bits that we need
36
*
37
* https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf
38
* Chapter "MANAGING STATE USING THE XSAVE FEATURE SET"
39
*/
40
#define XMM (1<<1)
41
#define YMM (1<<2)
42
#define OPMASK (1<<5)
43
#define ZMM0_15 (1<<6)
44
#define ZMM16_31 (1<<7)
45
46
47
/* array indexed by enum X86FeatureId */
48
bool
X86Features
[
X86FeaturesSize
] = {0};
49
50
static
bool
51
mask_available
(
uint32
value
,
uint32
mask)
52
{
53
return
(
value
& mask) == mask;
54
}
55
56
/* Named indexes for CPUID register array */
57
#define EAX 0
58
#define EBX 1
59
#define ECX 2
60
#define EDX 3
61
62
/*
63
* Request CPUID information for the specified leaf.
64
*/
65
static
inline
void
66
pg_cpuid
(
int
leaf
,
unsigned
int
*reg)
67
{
68
#if defined(HAVE__GET_CPUID)
69
__get_cpuid
(
leaf
, ®[
EAX
], ®[
EBX
], ®[
ECX
], ®[
EDX
]);
70
#elif defined(HAVE__CPUID)
71
__cpuid
((
int
*) reg,
leaf
);
72
#else
73
#error cpuid instruction not available
74
#endif
75
}
76
77
/*
78
* Request CPUID information for the specified leaf and subleaf.
79
*
80
* Returns true if the CPUID leaf/subleaf is supported, false otherwise.
81
*/
82
static
inline
bool
83
pg_cpuid_subleaf
(
int
leaf
,
int
subleaf
,
unsigned
int
*reg)
84
{
85
#if defined(HAVE__GET_CPUID_COUNT)
86
return
__get_cpuid_count
(
leaf
,
subleaf
, ®[
EAX
], ®[
EBX
], ®[
ECX
], ®[
EDX
]) == 1;
87
#elif defined(HAVE__CPUIDEX)
88
__cpuidex
((
int
*) reg,
leaf
,
subleaf
);
89
return
true
;
90
#else
91
memset
(reg, 0, 4 *
sizeof
(
unsigned
int
));
92
return
false
;
93
#endif
94
}
95
96
/*
97
* Parse the CPU ID info for runtime checks.
98
*/
99
#ifdef HAVE_XSAVE_INTRINSICS
100
pg_attribute_target
(
"xsave"
)
101
#endif
102
void
103
set_x86_features
(
void
)
104
{
105
unsigned
int
reg[4] = {0};
106
107
pg_cpuid
(0x01, reg);
108
109
X86Features
[
PG_SSE4_2
] = reg[
ECX
] >> 20 & 1;
110
X86Features
[
PG_POPCNT
] = reg[
ECX
] >> 23 & 1;
111
112
/* leaf 7 features that depend on OSXSAVE */
113
if
(reg[
ECX
] & (1 << 27))
114
{
115
uint32
xcr0_val
= 0;
116
117
pg_cpuid_subleaf
(0x07, 0, reg);
118
119
#ifdef HAVE_XSAVE_INTRINSICS
120
/* get value of Extended Control Register */
121
xcr0_val
=
_xgetbv
(0);
122
#endif
123
124
/* Are ZMM registers enabled? */
125
if
(
mask_available
(
xcr0_val
,
XMM
|
YMM
|
126
OPMASK
|
ZMM0_15
|
ZMM16_31
))
127
{
128
X86Features
[
PG_AVX512_BW
] = reg[
EBX
] >> 30 & 1;
129
X86Features
[
PG_AVX512_VL
] = reg[
EBX
] >> 31 & 1;
130
131
X86Features
[
PG_AVX512_VPCLMULQDQ
] = reg[
ECX
] >> 10 & 1;
132
X86Features
[
PG_AVX512_VPOPCNTDQ
] = reg[
ECX
] >> 14 & 1;
133
}
134
}
135
136
X86Features
[
INIT_PG_X86
] =
true
;
137
}
138
139
#endif
/* defined(USE_SSE2) || defined(__i386__) */
c.h
uint32
uint32_t uint32
Definition
c.h:618
pg_attribute_target
#define pg_attribute_target(...)
Definition
c.h:232
value
static struct @175 value
pg_cpu.h
fb
static int fb(int x)
Definition
preproc-init.c:92
src
port
pg_cpu_x86.c
Generated on Mon Mar 30 2026 12:13:18 for PostgreSQL Source Code by
1.9.8