summaryrefslogtreecommitdiffhomepage
path: root/ir/be/ia32/x86_architecture.h
blob: bc83c4f74b33101c0d4a3b7f6b41fa9095425eaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
 * @file
 * @brief   x86 architecture variants and feature definitions
 * @author  Johannes Bucher
 */
#ifndef FIRM_BE_X86_ARCHITECTURE_H
#define FIRM_BE_X86_ARCHITECTURE_H

#include "firm_types.h"
#include <stdbool.h>

#undef NATIVE_X86

#ifdef _MSC_VER
#if defined(_M_IX86) || defined(_M_X64)
#include <intrin.h>
#define NATIVE_X86
#endif
#else
#if defined(__i386__) || defined(__x86_64__)
#define NATIVE_X86
#endif
#endif

typedef enum x86_cpu_architectures {
	arch_generic          = 0x00000001, /**< no specific architecture */

	arch_i386             = 0x00000002, /**< i386 architecture */
	arch_i486             = 0x00000004, /**< i486 architecture */
	arch_pentium          = 0x00000008, /**< Pentium architecture */
	arch_ppro             = 0x00000010, /**< P6/PentiumPro architecture */
	arch_netburst         = 0x00000020, /**< Netburst architecture */
	arch_nocona           = 0x00000040, /**< Nocona architecture */
	arch_core2            = 0x00000080, /**< Core2 architecture */
	arch_atom             = 0x00000100, /**< Atom/Bonnell architecture */
	arch_silvermont       = 0x00000200, /**< Atom/Silvermont architecture */
	arch_goldmont         = 0x00000400, /**< Atom/Goldmont architecture */
	arch_goldmont_plus    = 0x00000800, /**< Atom/Goldmont Plus architecture */
	arch_tremont          = 0x00001000, /**< Atom/Tremont architecture */
	arch_nehalem          = 0x00002000, /**< Nehalem architecture */
	arch_sandybridge      = 0x00004000, /**< Sandy Bridge architecture */
	arch_haswell          = 0x00008000, /**< Haswell architecture */
	arch_skylake          = 0x00010000, /**< Skylake architecture */
	arch_sunnycove        = 0x00020000, /**< Sunny Cove architecture */

	arch_k6               = 0x00100000, /**< K6 architecture */
	arch_geode            = 0x00200000, /**< Geode architecture */
	arch_athlon           = 0x00400000, /**< Athlon architecture */
	arch_k8               = 0x00800000, /**< K8/Opteron architecture */
	arch_k10              = 0x01000000, /**< K10/Barcelona architecture */
	arch_amdfam15h        = 0x02000000, /**< Bulldozer architecture */
	arch_amdfam14h        = 0x04000000, /**< Bobcat architecture */
	arch_amdfam16h        = 0x08000000, /**< Jaguar/Puma architecture */
	arch_amdfam17h        = 0x10000000, /**< Zen/Zen+/Zen2 architecture */
	arch_amdfam19h        = 0x20000000, /**< Zen3 architecture */

	arch_athlon_plus      = arch_athlon | arch_k8 | arch_k10 | arch_amdfam15h | arch_amdfam14h | arch_amdfam16h |
							arch_amdfam17h | arch_amdfam19h,
	arch_all_amd          = arch_k6 | arch_geode | arch_athlon_plus,
	arch_core2_plus       = arch_core2 | arch_nehalem | arch_sandybridge | arch_haswell | arch_skylake | arch_sunnycove,
	arch_atom_plus        = arch_atom | arch_silvermont | arch_goldmont | arch_goldmont_plus | arch_tremont

} x86_cpu_architectures;
ENUM_BITSET(x86_cpu_architectures)

/**
 * CPU architectures and features.
 */
typedef enum x86_cpu_features {

	arch_feature_none     = 0,

	arch_feature_mmx      = 0x00000001, /**< MMX instructions */
	arch_feature_cmov     = 0x00000002, /**< cmov instructions */
	arch_feature_fcmov    = 0x00000004, /**< FCMOV/F(U)COMI(P) instructions */
	arch_feature_sse1     = 0x00000008, /**< SSE1 instructions */
	arch_feature_sse2     = 0x00000010, /**< SSE2 instructions */
	arch_feature_sse3     = 0x00000020, /**< SSE3 instructions */
	arch_feature_ssse3    = 0x00000040, /**< SSSE3 instructions */
	arch_feature_3DNow    = 0x00000080, /**< 3DNow! instructions */
	arch_feature_3DNowE   = 0x00000100, /**< Enhanced 3DNow! instructions */
	arch_feature_64bit    = 0x00000200, /**< x86_64 support */
	arch_feature_sse4_1   = 0x00000400, /**< SSE4.1 instructions */
	arch_feature_sse4_2   = 0x00000800, /**< SSE4.2 instructions */
	arch_feature_sse4a    = 0x00001000, /**< SSE4a instructions */
	arch_feature_popcnt   = 0x00002000, /**< popcnt instruction */
	arch_feature_fma      = 0x00004000, /**< FMA instructions */
	arch_feature_avx      = 0x00008000, /**< AVX instructions */
	arch_feature_avx2     = 0x00010000, /**< AVX2 instructions */


	arch_mmx_insn     = arch_feature_mmx,                         /**< MMX instructions */
	arch_sse1_insn    = arch_feature_sse1   | arch_mmx_insn,      /**< SSE1 instructions, include MMX */
	arch_sse2_insn    = arch_feature_sse2   | arch_sse1_insn,     /**< SSE2 instructions, include SSE1 */
	arch_sse3_insn    = arch_feature_sse3   | arch_sse2_insn,     /**< SSE3 instructions, include SSE2 */
	arch_ssse3_insn   = arch_feature_ssse3  | arch_sse3_insn,     /**< SSSE3 instructions, include SSE3 */
	arch_sse4_1_insn  = arch_feature_sse4_1 | arch_ssse3_insn,    /**< SSE4.1 instructions, include SSSE3 */
	arch_sse4_2_insn  = arch_feature_sse4_2 | arch_sse4_1_insn,   /**< SSE4.2 instructions, include SSE4.1 */
	arch_sse4a_insn   = arch_feature_sse4a  | arch_ssse3_insn,    /**< SSE4a instructions, include SSSE3 */
	arch_avx_insn     = arch_feature_avx    | arch_sse4_2_insn,   /**< AVX instructions, include SSE4.2 */
	arch_avx2_insn    = arch_feature_avx2   | arch_avx_insn,      /**< AVX2 instructions, include AVX */

	arch_3DNow_insn   = arch_feature_3DNow  | arch_feature_mmx,   /**< 3DNow! instructions, including MMX */
	arch_3DNowE_insn  = arch_feature_3DNowE | arch_3DNow_insn,    /**< Enhanced 3DNow! instructions */
	arch_64bit_insn   = arch_feature_64bit  | arch_sse2_insn,     /**< x86_64 support, includes SSE2 */

} x86_cpu_features;
ENUM_BITSET(x86_cpu_features)

typedef struct cpu_arch_features {
	x86_cpu_architectures arch;
	x86_cpu_features features;
} cpu_arch_features;

/* cpu variants (selectable through -march=.../-mtune=... options) */
typedef enum x86_cpu {
	cpu_autodetect = 0,
	cpu_generic = 1,
	cpu_generic64,

	/* Intel CPUs */
	cpu_i386,
	cpu_i486,
	cpu_pentium,
	cpu_pentium_mmx,
	cpu_pentium_pro,
	cpu_pentium_2,
	cpu_pentium_3,
	cpu_pentium_m,
	cpu_pentium_4,
	cpu_prescott,
	cpu_nocona,
	cpu_core2,
	cpu_penryn,
	cpu_nehalem,
	cpu_westmere,
	cpu_sandybridge,
	cpu_ivybridge,
	cpu_haswell,
	cpu_broadwell,
	cpu_skylake,
	cpu_skylake_avx512,
	cpu_cascade_lake,
	cpu_cooperlake,
	cpu_cannonlake,
	cpu_icelake_client,
	cpu_icelake_server,
	cpu_tigerlake,
	cpu_sapphirerapids,
	cpu_alderlake,

	cpu_atom,
	cpu_silvermont,
	cpu_goldmont,
	cpu_goldmont_plus,
	cpu_tremont,
	cpu_knl,
	cpu_knm,

	/* AMD CPUs */
	cpu_k6,
	cpu_k6_PLUS,
	cpu_geode,
	cpu_athlon_old,
	cpu_athlon,
	cpu_athlon64,
	cpu_k8,
	cpu_k8_sse3,
	cpu_k10,
	cpu_btver1,
	cpu_btver2,
	cpu_bdver1,
	cpu_bdver2,
	cpu_bdver3,
	cpu_bdver4,
	cpu_znver1,
	cpu_znver2,
	cpu_znver3,

	/* other CPUs */
	cpu_winchip_c6,
	cpu_winchip2,
	cpu_c3,
	cpu_c3_2,

	cpu_max
} x86_cpu;

extern cpu_arch_features cpu_arch_feature_defs[];

cpu_arch_features autodetect_arch(void);

bool arch_flags(cpu_arch_features arch_features, x86_cpu_architectures flags);

bool feature_flags(cpu_arch_features arch_features, x86_cpu_features flags);

#endif