cranelift_codegen_meta/isa/
x86.rs

1use crate::cdsl::isa::TargetIsa;
2use crate::cdsl::settings::SettingGroupBuilder;
3
4pub(crate) fn define() -> TargetIsa {
5    let mut settings = SettingGroupBuilder::new("x86");
6
7    // CPUID.01H:ECX
8    let has_sse3 = settings.add_bool(
9        "has_sse3",
10        "Has support for SSE3.",
11        "SSE3: CPUID.01H:ECX.SSE3[bit 0]",
12        false,
13    );
14    let has_ssse3 = settings.add_bool(
15        "has_ssse3",
16        "Has support for SSSE3.",
17        "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]",
18        false,
19    );
20    let has_cmpxchg16b = settings.add_bool(
21        "has_cmpxchg16b",
22        "Has support for CMPXCHG16b.",
23        "CMPXCHG16b: CPUID.01H:ECX.CMPXCHG16B[bit 13]",
24        false,
25    );
26    let has_sse41 = settings.add_bool(
27        "has_sse41",
28        "Has support for SSE4.1.",
29        "SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]",
30        false,
31    );
32    let has_sse42 = settings.add_bool(
33        "has_sse42",
34        "Has support for SSE4.2.",
35        "SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]",
36        false,
37    );
38    let has_avx = settings.add_bool(
39        "has_avx",
40        "Has support for AVX.",
41        "AVX: CPUID.01H:ECX.AVX[bit 28]",
42        false,
43    );
44    let has_avx2 = settings.add_bool(
45        "has_avx2",
46        "Has support for AVX2.",
47        "AVX2: CPUID.07H:EBX.AVX2[bit 5]",
48        false,
49    );
50    let has_fma = settings.add_bool(
51        "has_fma",
52        "Has support for FMA.",
53        "FMA: CPUID.01H:ECX.FMA[bit 12]",
54        false,
55    );
56    let has_avx512bitalg = settings.add_bool(
57        "has_avx512bitalg",
58        "Has support for AVX512BITALG.",
59        "AVX512BITALG: CPUID.07H:ECX.AVX512BITALG[bit 12]",
60        false,
61    );
62    let has_avx512dq = settings.add_bool(
63        "has_avx512dq",
64        "Has support for AVX512DQ.",
65        "AVX512DQ: CPUID.07H:EBX.AVX512DQ[bit 17]",
66        false,
67    );
68    let has_avx512vl = settings.add_bool(
69        "has_avx512vl",
70        "Has support for AVX512VL.",
71        "AVX512VL: CPUID.07H:EBX.AVX512VL[bit 31]",
72        false,
73    );
74    let has_avx512vbmi = settings.add_bool(
75        "has_avx512vbmi",
76        "Has support for AVX512VMBI.",
77        "AVX512VBMI: CPUID.07H:ECX.AVX512VBMI[bit 1]",
78        false,
79    );
80    let has_avx512f = settings.add_bool(
81        "has_avx512f",
82        "Has support for AVX512F.",
83        "AVX512F: CPUID.07H:EBX.AVX512F[bit 16]",
84        false,
85    );
86    let has_popcnt = settings.add_bool(
87        "has_popcnt",
88        "Has support for POPCNT.",
89        "POPCNT: CPUID.01H:ECX.POPCNT[bit 23]",
90        false,
91    );
92
93    // CPUID.(EAX=07H, ECX=0H):EBX
94    let has_bmi1 = settings.add_bool(
95        "has_bmi1",
96        "Has support for BMI1.",
97        "BMI1: CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]",
98        false,
99    );
100    let has_bmi2 = settings.add_bool(
101        "has_bmi2",
102        "Has support for BMI2.",
103        "BMI2: CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]",
104        false,
105    );
106
107    // CPUID.EAX=80000001H:ECX
108    let has_lzcnt = settings.add_bool(
109        "has_lzcnt",
110        "Has support for LZCNT.",
111        "LZCNT: CPUID.EAX=80000001H:ECX.LZCNT[bit 5]",
112        false,
113    );
114
115    let sse3 = settings.add_preset("sse3", "SSE3 and earlier.", preset!(has_sse3));
116    let ssse3 = settings.add_preset("ssse3", "SSSE3 and earlier.", preset!(sse3 && has_ssse3));
117    let sse41 = settings.add_preset("sse41", "SSE4.1 and earlier.", preset!(ssse3 && has_sse41));
118    let sse42 = settings.add_preset("sse42", "SSE4.2 and earlier.", preset!(sse41 && has_sse42));
119
120    // Presets corresponding to x86 CPUs.
121    // Features and architecture names are from LLVM's x86 presets:
122    // https://github.com/llvm/llvm-project/blob/d4493dd1ed58ac3f1eab0c4ca6e363e2b15bfd1c/llvm/lib/Target/X86/X86.td#L1300-L1643
123    settings.add_preset(
124        "baseline",
125        "A baseline preset with no extensions enabled.",
126        preset!(),
127    );
128
129    // Intel CPUs
130
131    // Netburst
132    settings.add_preset(
133        "nocona",
134        "Nocona microarchitecture.",
135        preset!(sse3 && has_cmpxchg16b),
136    );
137
138    // Intel Core 2 Solo/Duo
139    settings.add_preset(
140        "core2",
141        "Core 2 microarchitecture.",
142        preset!(sse3 && has_cmpxchg16b),
143    );
144    settings.add_preset(
145        "penryn",
146        "Penryn microarchitecture.",
147        preset!(sse41 && has_cmpxchg16b),
148    );
149
150    // Intel Atom CPUs
151    let atom = settings.add_preset(
152        "atom",
153        "Atom microarchitecture.",
154        preset!(ssse3 && has_cmpxchg16b),
155    );
156    settings.add_preset("bonnell", "Bonnell microarchitecture.", preset!(atom));
157    let silvermont = settings.add_preset(
158        "silvermont",
159        "Silvermont microarchitecture.",
160        preset!(atom && sse42 && has_popcnt),
161    );
162    settings.add_preset("slm", "Silvermont microarchitecture.", preset!(silvermont));
163    let goldmont = settings.add_preset(
164        "goldmont",
165        "Goldmont microarchitecture.",
166        preset!(silvermont),
167    );
168    settings.add_preset(
169        "goldmont-plus",
170        "Goldmont Plus microarchitecture.",
171        preset!(goldmont),
172    );
173    let tremont = settings.add_preset("tremont", "Tremont microarchitecture.", preset!(goldmont));
174
175    let alderlake = settings.add_preset(
176        "alderlake",
177        "Alderlake microarchitecture.",
178        preset!(tremont && has_bmi1 && has_bmi2 && has_lzcnt && has_fma),
179    );
180    let sierra_forest = settings.add_preset(
181        "sierraforest",
182        "Sierra Forest microarchitecture.",
183        preset!(alderlake),
184    );
185    settings.add_preset(
186        "grandridge",
187        "Grandridge microarchitecture.",
188        preset!(sierra_forest),
189    );
190    let nehalem = settings.add_preset(
191        "nehalem",
192        "Nehalem microarchitecture.",
193        preset!(sse42 && has_popcnt && has_cmpxchg16b),
194    );
195    settings.add_preset("corei7", "Core i7 microarchitecture.", preset!(nehalem));
196    let westmere = settings.add_preset("westmere", "Westmere microarchitecture.", preset!(nehalem));
197    let sandy_bridge = settings.add_preset(
198        "sandybridge",
199        "Sandy Bridge microarchitecture.",
200        preset!(westmere && has_avx),
201    );
202    settings.add_preset(
203        "corei7-avx",
204        "Core i7 AVX microarchitecture.",
205        preset!(sandy_bridge),
206    );
207    let ivy_bridge = settings.add_preset(
208        "ivybridge",
209        "Ivy Bridge microarchitecture.",
210        preset!(sandy_bridge),
211    );
212    settings.add_preset(
213        "core-avx-i",
214        "Intel Core CPU with 64-bit extensions.",
215        preset!(ivy_bridge),
216    );
217    let haswell = settings.add_preset(
218        "haswell",
219        "Haswell microarchitecture.",
220        preset!(ivy_bridge && has_avx2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt),
221    );
222    settings.add_preset(
223        "core-avx2",
224        "Intel Core CPU with AVX2 extensions.",
225        preset!(haswell),
226    );
227    let broadwell = settings.add_preset(
228        "broadwell",
229        "Broadwell microarchitecture.",
230        preset!(haswell),
231    );
232    let skylake = settings.add_preset("skylake", "Skylake microarchitecture.", preset!(broadwell));
233    let knights_landing = settings.add_preset(
234        "knl",
235        "Knights Landing microarchitecture.",
236        preset!(
237            has_popcnt
238                && has_avx512f
239                && has_fma
240                && has_bmi1
241                && has_bmi2
242                && has_lzcnt
243                && has_cmpxchg16b
244        ),
245    );
246    settings.add_preset(
247        "knm",
248        "Knights Mill microarchitecture.",
249        preset!(knights_landing),
250    );
251    let skylake_avx512 = settings.add_preset(
252        "skylake-avx512",
253        "Skylake AVX512 microarchitecture.",
254        preset!(broadwell && has_avx512f && has_avx512dq && has_avx512vl),
255    );
256    settings.add_preset(
257        "skx",
258        "Skylake AVX512 microarchitecture.",
259        preset!(skylake_avx512),
260    );
261    let cascadelake = settings.add_preset(
262        "cascadelake",
263        "Cascade Lake microarchitecture.",
264        preset!(skylake_avx512),
265    );
266    settings.add_preset(
267        "cooperlake",
268        "Cooper Lake microarchitecture.",
269        preset!(cascadelake),
270    );
271    let cannonlake = settings.add_preset(
272        "cannonlake",
273        "Canon Lake microarchitecture.",
274        preset!(skylake && has_avx512f && has_avx512dq && has_avx512vl && has_avx512vbmi),
275    );
276    let icelake_client = settings.add_preset(
277        "icelake-client",
278        "Ice Lake microarchitecture.",
279        preset!(cannonlake && has_avx512bitalg),
280    );
281    // LLVM doesn't use the name "icelake" but Cranelift did in the past; alias it
282    settings.add_preset(
283        "icelake",
284        "Ice Lake microarchitecture",
285        preset!(icelake_client),
286    );
287    let icelake_server = settings.add_preset(
288        "icelake-server",
289        "Ice Lake (server) microarchitecture.",
290        preset!(icelake_client),
291    );
292    settings.add_preset(
293        "tigerlake",
294        "Tiger Lake microarchitecture.",
295        preset!(icelake_client),
296    );
297    let sapphire_rapids = settings.add_preset(
298        "sapphirerapids",
299        "Sapphire Rapids microarchitecture.",
300        preset!(icelake_server),
301    );
302    settings.add_preset(
303        "raptorlake",
304        "Raptor Lake microarchitecture.",
305        preset!(alderlake),
306    );
307    settings.add_preset(
308        "meteorlake",
309        "Meteor Lake microarchitecture.",
310        preset!(alderlake),
311    );
312    settings.add_preset(
313        "graniterapids",
314        "Granite Rapids microarchitecture.",
315        preset!(sapphire_rapids),
316    );
317
318    // AMD CPUs
319
320    settings.add_preset("opteron", "Opteron microarchitecture.", preset!());
321    settings.add_preset("k8", "K8 Hammer microarchitecture.", preset!());
322    settings.add_preset("athlon64", "Athlon64 microarchitecture.", preset!());
323    settings.add_preset("athlon-fx", "Athlon FX microarchitecture.", preset!());
324    settings.add_preset(
325        "opteron-sse3",
326        "Opteron microarchitecture with support for SSE3 instructions.",
327        preset!(sse3 && has_cmpxchg16b),
328    );
329    settings.add_preset(
330        "k8-sse3",
331        "K8 Hammer microarchitecture with support for SSE3 instructions.",
332        preset!(sse3 && has_cmpxchg16b),
333    );
334    settings.add_preset(
335        "athlon64-sse3",
336        "Athlon 64 microarchitecture with support for SSE3 instructions.",
337        preset!(sse3 && has_cmpxchg16b),
338    );
339    let barcelona = settings.add_preset(
340        "barcelona",
341        "Barcelona microarchitecture.",
342        preset!(has_popcnt && has_lzcnt && has_cmpxchg16b),
343    );
344    settings.add_preset(
345        "amdfam10",
346        "AMD Family 10h microarchitecture",
347        preset!(barcelona),
348    );
349
350    let btver1 = settings.add_preset(
351        "btver1",
352        "Bobcat microarchitecture.",
353        preset!(ssse3 && has_lzcnt && has_popcnt && has_cmpxchg16b),
354    );
355    settings.add_preset(
356        "btver2",
357        "Jaguar microarchitecture.",
358        preset!(btver1 && has_avx && has_bmi1),
359    );
360
361    let bdver1 = settings.add_preset(
362        "bdver1",
363        "Bulldozer microarchitecture",
364        preset!(has_lzcnt && has_popcnt && ssse3 && has_cmpxchg16b),
365    );
366    let bdver2 = settings.add_preset(
367        "bdver2",
368        "Piledriver microarchitecture.",
369        preset!(bdver1 && has_bmi1),
370    );
371    let bdver3 = settings.add_preset("bdver3", "Steamroller microarchitecture.", preset!(bdver2));
372    settings.add_preset(
373        "bdver4",
374        "Excavator microarchitecture.",
375        preset!(bdver3 && has_avx2 && has_bmi2),
376    );
377
378    let znver1 = settings.add_preset(
379        "znver1",
380        "Zen (first generation) microarchitecture.",
381        preset!(
382            sse42 && has_popcnt && has_bmi1 && has_bmi2 && has_lzcnt && has_fma && has_cmpxchg16b
383        ),
384    );
385    let znver2 = settings.add_preset(
386        "znver2",
387        "Zen (second generation) microarchitecture.",
388        preset!(znver1),
389    );
390    let znver3 = settings.add_preset(
391        "znver3",
392        "Zen (third generation) microarchitecture.",
393        preset!(znver2),
394    );
395    settings.add_preset(
396        "znver4",
397        "Zen (fourth generation) microarchitecture.",
398        preset!(
399            znver3
400                && has_avx512bitalg
401                && has_avx512dq
402                && has_avx512f
403                && has_avx512vbmi
404                && has_avx512vl
405        ),
406    );
407
408    // Generic
409
410    settings.add_preset("x86-64", "Generic x86-64 microarchitecture.", preset!());
411    let x86_64_v2 = settings.add_preset(
412        "x86-64-v2",
413        "Generic x86-64 (V2) microarchitecture.",
414        preset!(sse42 && has_popcnt && has_cmpxchg16b),
415    );
416    let x86_64_v3 = settings.add_preset(
417        "x84_64_v3",
418        "Generic x86_64 (V3) microarchitecture.",
419        preset!(x86_64_v2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt && has_avx2),
420    );
421    settings.add_preset(
422        "x86_64_v4",
423        "Generic x86_64 (V4) microarchitecture.",
424        preset!(x86_64_v3 && has_avx512dq && has_avx512vl),
425    );
426
427    TargetIsa::new("x86", settings.build())
428}