cranelift_codegen_meta/isa/
x86.rs

1use crate::cdsl::isa::TargetIsa;
2use crate::cdsl::settings::{PredicateNode, 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    settings.add_predicate("use_cmpxchg16b", predicate!(has_cmpxchg16b));
116    settings.add_predicate("use_ssse3", predicate!(has_ssse3));
117    settings.add_predicate("use_sse41", predicate!(has_sse41));
118    settings.add_predicate("use_sse42", predicate!(has_sse41 && has_sse42));
119    settings.add_predicate("use_fma", predicate!(has_avx && has_fma));
120
121    settings.add_predicate("use_avx", predicate!(has_avx));
122    settings.add_predicate("use_avx2", predicate!(has_avx && has_avx2));
123    settings.add_predicate("use_avx512bitalg", predicate!(has_avx512bitalg));
124    settings.add_predicate("use_avx512dq", predicate!(has_avx512dq));
125    settings.add_predicate("use_avx512vl", predicate!(has_avx512vl));
126    settings.add_predicate("use_avx512vbmi", predicate!(has_avx512vbmi));
127    settings.add_predicate("use_avx512f", predicate!(has_avx512f));
128
129    settings.add_predicate("use_popcnt", predicate!(has_popcnt && has_sse42));
130    settings.add_predicate("use_bmi1", predicate!(has_bmi1));
131    settings.add_predicate("use_bmi2", predicate!(has_bmi2));
132    settings.add_predicate("use_lzcnt", predicate!(has_lzcnt));
133
134    let sse3 = settings.add_preset("sse3", "SSE3 and earlier.", preset!(has_sse3));
135    let ssse3 = settings.add_preset("ssse3", "SSSE3 and earlier.", preset!(sse3 && has_ssse3));
136    let sse41 = settings.add_preset("sse41", "SSE4.1 and earlier.", preset!(ssse3 && has_sse41));
137    let sse42 = settings.add_preset("sse42", "SSE4.2 and earlier.", preset!(sse41 && has_sse42));
138
139    // Presets corresponding to x86 CPUs.
140    // Features and architecture names are from LLVM's x86 presets:
141    // https://github.com/llvm/llvm-project/blob/d4493dd1ed58ac3f1eab0c4ca6e363e2b15bfd1c/llvm/lib/Target/X86/X86.td#L1300-L1643
142    settings.add_preset(
143        "baseline",
144        "A baseline preset with no extensions enabled.",
145        preset!(),
146    );
147
148    // Intel CPUs
149
150    // Netburst
151    settings.add_preset(
152        "nocona",
153        "Nocona microarchitecture.",
154        preset!(sse3 && has_cmpxchg16b),
155    );
156
157    // Intel Core 2 Solo/Duo
158    settings.add_preset(
159        "core2",
160        "Core 2 microarchitecture.",
161        preset!(sse3 && has_cmpxchg16b),
162    );
163    settings.add_preset(
164        "penryn",
165        "Penryn microarchitecture.",
166        preset!(sse41 && has_cmpxchg16b),
167    );
168
169    // Intel Atom CPUs
170    let atom = settings.add_preset(
171        "atom",
172        "Atom microarchitecture.",
173        preset!(ssse3 && has_cmpxchg16b),
174    );
175    settings.add_preset("bonnell", "Bonnell microarchitecture.", preset!(atom));
176    let silvermont = settings.add_preset(
177        "silvermont",
178        "Silvermont microarchitecture.",
179        preset!(atom && sse42 && has_popcnt),
180    );
181    settings.add_preset("slm", "Silvermont microarchitecture.", preset!(silvermont));
182    let goldmont = settings.add_preset(
183        "goldmont",
184        "Goldmont microarchitecture.",
185        preset!(silvermont),
186    );
187    settings.add_preset(
188        "goldmont-plus",
189        "Goldmont Plus microarchitecture.",
190        preset!(goldmont),
191    );
192    let tremont = settings.add_preset("tremont", "Tremont microarchitecture.", preset!(goldmont));
193
194    let alderlake = settings.add_preset(
195        "alderlake",
196        "Alderlake microarchitecture.",
197        preset!(tremont && has_bmi1 && has_bmi2 && has_lzcnt && has_fma),
198    );
199    let sierra_forest = settings.add_preset(
200        "sierraforest",
201        "Sierra Forest microarchitecture.",
202        preset!(alderlake),
203    );
204    settings.add_preset(
205        "grandridge",
206        "Grandridge microarchitecture.",
207        preset!(sierra_forest),
208    );
209    let nehalem = settings.add_preset(
210        "nehalem",
211        "Nehalem microarchitecture.",
212        preset!(sse42 && has_popcnt && has_cmpxchg16b),
213    );
214    settings.add_preset("corei7", "Core i7 microarchitecture.", preset!(nehalem));
215    let westmere = settings.add_preset("westmere", "Westmere microarchitecture.", preset!(nehalem));
216    let sandy_bridge = settings.add_preset(
217        "sandybridge",
218        "Sandy Bridge microarchitecture.",
219        preset!(westmere && has_avx),
220    );
221    settings.add_preset(
222        "corei7-avx",
223        "Core i7 AVX microarchitecture.",
224        preset!(sandy_bridge),
225    );
226    let ivy_bridge = settings.add_preset(
227        "ivybridge",
228        "Ivy Bridge microarchitecture.",
229        preset!(sandy_bridge),
230    );
231    settings.add_preset(
232        "core-avx-i",
233        "Intel Core CPU with 64-bit extensions.",
234        preset!(ivy_bridge),
235    );
236    let haswell = settings.add_preset(
237        "haswell",
238        "Haswell microarchitecture.",
239        preset!(ivy_bridge && has_avx2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt),
240    );
241    settings.add_preset(
242        "core-avx2",
243        "Intel Core CPU with AVX2 extensions.",
244        preset!(haswell),
245    );
246    let broadwell = settings.add_preset(
247        "broadwell",
248        "Broadwell microarchitecture.",
249        preset!(haswell),
250    );
251    let skylake = settings.add_preset("skylake", "Skylake microarchitecture.", preset!(broadwell));
252    let knights_landing = settings.add_preset(
253        "knl",
254        "Knights Landing microarchitecture.",
255        preset!(
256            has_popcnt
257                && has_avx512f
258                && has_fma
259                && has_bmi1
260                && has_bmi2
261                && has_lzcnt
262                && has_cmpxchg16b
263        ),
264    );
265    settings.add_preset(
266        "knm",
267        "Knights Mill microarchitecture.",
268        preset!(knights_landing),
269    );
270    let skylake_avx512 = settings.add_preset(
271        "skylake-avx512",
272        "Skylake AVX512 microarchitecture.",
273        preset!(broadwell && has_avx512f && has_avx512dq && has_avx512vl),
274    );
275    settings.add_preset(
276        "skx",
277        "Skylake AVX512 microarchitecture.",
278        preset!(skylake_avx512),
279    );
280    let cascadelake = settings.add_preset(
281        "cascadelake",
282        "Cascade Lake microarchitecture.",
283        preset!(skylake_avx512),
284    );
285    settings.add_preset(
286        "cooperlake",
287        "Cooper Lake microarchitecture.",
288        preset!(cascadelake),
289    );
290    let cannonlake = settings.add_preset(
291        "cannonlake",
292        "Canon Lake microarchitecture.",
293        preset!(skylake && has_avx512f && has_avx512dq && has_avx512vl && has_avx512vbmi),
294    );
295    let icelake_client = settings.add_preset(
296        "icelake-client",
297        "Ice Lake microarchitecture.",
298        preset!(cannonlake && has_avx512bitalg),
299    );
300    // LLVM doesn't use the name "icelake" but Cranelift did in the past; alias it
301    settings.add_preset(
302        "icelake",
303        "Ice Lake microarchitecture",
304        preset!(icelake_client),
305    );
306    let icelake_server = settings.add_preset(
307        "icelake-server",
308        "Ice Lake (server) microarchitecture.",
309        preset!(icelake_client),
310    );
311    settings.add_preset(
312        "tigerlake",
313        "Tiger Lake microarchitecture.",
314        preset!(icelake_client),
315    );
316    let sapphire_rapids = settings.add_preset(
317        "sapphirerapids",
318        "Sapphire Rapids microarchitecture.",
319        preset!(icelake_server),
320    );
321    settings.add_preset(
322        "raptorlake",
323        "Raptor Lake microarchitecture.",
324        preset!(alderlake),
325    );
326    settings.add_preset(
327        "meteorlake",
328        "Meteor Lake microarchitecture.",
329        preset!(alderlake),
330    );
331    settings.add_preset(
332        "graniterapids",
333        "Granite Rapids microarchitecture.",
334        preset!(sapphire_rapids),
335    );
336
337    // AMD CPUs
338
339    settings.add_preset("opteron", "Opteron microarchitecture.", preset!());
340    settings.add_preset("k8", "K8 Hammer microarchitecture.", preset!());
341    settings.add_preset("athlon64", "Athlon64 microarchitecture.", preset!());
342    settings.add_preset("athlon-fx", "Athlon FX microarchitecture.", preset!());
343    settings.add_preset(
344        "opteron-sse3",
345        "Opteron microarchitecture with support for SSE3 instructions.",
346        preset!(sse3 && has_cmpxchg16b),
347    );
348    settings.add_preset(
349        "k8-sse3",
350        "K8 Hammer microarchitecture with support for SSE3 instructions.",
351        preset!(sse3 && has_cmpxchg16b),
352    );
353    settings.add_preset(
354        "athlon64-sse3",
355        "Athlon 64 microarchitecture with support for SSE3 instructions.",
356        preset!(sse3 && has_cmpxchg16b),
357    );
358    let barcelona = settings.add_preset(
359        "barcelona",
360        "Barcelona microarchitecture.",
361        preset!(has_popcnt && has_lzcnt && has_cmpxchg16b),
362    );
363    settings.add_preset(
364        "amdfam10",
365        "AMD Family 10h microarchitecture",
366        preset!(barcelona),
367    );
368
369    let btver1 = settings.add_preset(
370        "btver1",
371        "Bobcat microarchitecture.",
372        preset!(ssse3 && has_lzcnt && has_popcnt && has_cmpxchg16b),
373    );
374    settings.add_preset(
375        "btver2",
376        "Jaguar microarchitecture.",
377        preset!(btver1 && has_avx && has_bmi1),
378    );
379
380    let bdver1 = settings.add_preset(
381        "bdver1",
382        "Bulldozer microarchitecture",
383        preset!(has_lzcnt && has_popcnt && ssse3 && has_cmpxchg16b),
384    );
385    let bdver2 = settings.add_preset(
386        "bdver2",
387        "Piledriver microarchitecture.",
388        preset!(bdver1 && has_bmi1),
389    );
390    let bdver3 = settings.add_preset("bdver3", "Steamroller microarchitecture.", preset!(bdver2));
391    settings.add_preset(
392        "bdver4",
393        "Excavator microarchitecture.",
394        preset!(bdver3 && has_avx2 && has_bmi2),
395    );
396
397    let znver1 = settings.add_preset(
398        "znver1",
399        "Zen (first generation) microarchitecture.",
400        preset!(
401            sse42 && has_popcnt && has_bmi1 && has_bmi2 && has_lzcnt && has_fma && has_cmpxchg16b
402        ),
403    );
404    let znver2 = settings.add_preset(
405        "znver2",
406        "Zen (second generation) microarchitecture.",
407        preset!(znver1),
408    );
409    let znver3 = settings.add_preset(
410        "znver3",
411        "Zen (third generation) microarchitecture.",
412        preset!(znver2),
413    );
414    settings.add_preset(
415        "znver4",
416        "Zen (fourth generation) microarchitecture.",
417        preset!(
418            znver3
419                && has_avx512bitalg
420                && has_avx512dq
421                && has_avx512f
422                && has_avx512vbmi
423                && has_avx512vl
424        ),
425    );
426
427    // Generic
428
429    settings.add_preset("x86-64", "Generic x86-64 microarchitecture.", preset!());
430    let x86_64_v2 = settings.add_preset(
431        "x86-64-v2",
432        "Generic x86-64 (V2) microarchitecture.",
433        preset!(sse42 && has_popcnt && has_cmpxchg16b),
434    );
435    let x86_64_v3 = settings.add_preset(
436        "x84_64_v3",
437        "Generic x86_64 (V3) microarchitecture.",
438        preset!(x86_64_v2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt && has_avx2),
439    );
440    settings.add_preset(
441        "x86_64_v4",
442        "Generic x86_64 (V4) microarchitecture.",
443        preset!(x86_64_v3 && has_avx512dq && has_avx512vl),
444    );
445
446    TargetIsa::new("x86", settings.build())
447}