master
1const std = @import("std");
2const builtin = @import("builtin");
3const fs = std.fs;
4const mem = std.mem;
5const json = std.json;
6const assert = std.debug.assert;
7
8// All references to other features are based on "zig name" as the key.
9
10const FeatureOverride = struct {
11 llvm_name: []const u8,
12 /// If true, completely omit the feature; as if it does not exist.
13 omit: bool = false,
14 /// If true, omit the feature, but all the dependencies of the feature
15 /// are added in its place.
16 flatten: bool = false,
17 zig_name: ?[]const u8 = null,
18 desc: ?[]const u8 = null,
19 omit_deps: []const []const u8 = &.{},
20 extra_deps: []const []const u8 = &.{},
21};
22
23const Cpu = struct {
24 llvm_name: ?[]const u8,
25 zig_name: []const u8,
26 features: []const []const u8,
27};
28
29const Feature = struct {
30 llvm_name: ?[]const u8 = null,
31 zig_name: []const u8,
32 desc: []const u8,
33 deps: []const []const u8,
34 flatten: bool = false,
35};
36
37const ArchTarget = struct {
38 zig_name: []const u8,
39 llvm: ?struct {
40 name: []const u8,
41 td_name: []const u8,
42 },
43 feature_overrides: []const FeatureOverride = &.{},
44 extra_cpus: []const Cpu = &.{},
45 extra_features: []const Feature = &.{},
46 omit_cpus: []const []const u8 = &.{},
47 branch_quota: ?usize = null,
48};
49
50const targets = [_]ArchTarget{
51 .{
52 .zig_name = "aarch64",
53 .llvm = .{
54 .name = "AArch64",
55 .td_name = "AArch64",
56 },
57 .branch_quota = 2000,
58 .feature_overrides = &.{
59 .{
60 .llvm_name = "all",
61 .omit = true,
62 },
63 .{
64 .llvm_name = "CONTEXTIDREL2",
65 .zig_name = "contextidr_el2",
66 .desc = "Enable RW operand Context ID Register (EL2)",
67 },
68 .{
69 .llvm_name = "neoversee1",
70 .flatten = true,
71 },
72 .{
73 .llvm_name = "neoversen1",
74 .flatten = true,
75 },
76 .{
77 .llvm_name = "neoversen2",
78 .flatten = true,
79 },
80 .{
81 .llvm_name = "neoversen3",
82 .flatten = true,
83 },
84 .{
85 .llvm_name = "neoversev1",
86 .flatten = true,
87 },
88 .{
89 .llvm_name = "neoversev2",
90 .flatten = true,
91 },
92 .{
93 .llvm_name = "neoversev3",
94 .flatten = true,
95 },
96 .{
97 .llvm_name = "neoversev3AE",
98 .flatten = true,
99 },
100 .{
101 .llvm_name = "neoverse512tvb",
102 .flatten = true,
103 },
104 .{
105 .llvm_name = "oryon-1",
106 .flatten = true,
107 },
108 .{
109 .llvm_name = "exynosm3",
110 .flatten = true,
111 },
112 .{
113 .llvm_name = "exynosm4",
114 .flatten = true,
115 },
116 .{
117 .llvm_name = "a35",
118 .flatten = true,
119 },
120 .{
121 .llvm_name = "a53",
122 .flatten = true,
123 },
124 .{
125 .llvm_name = "a55",
126 .flatten = true,
127 },
128 .{
129 .llvm_name = "a57",
130 .flatten = true,
131 },
132 .{
133 .llvm_name = "a510",
134 .flatten = true,
135 },
136 .{
137 .llvm_name = "a520",
138 .flatten = true,
139 },
140 .{
141 .llvm_name = "a520ae",
142 .flatten = true,
143 },
144 .{
145 .llvm_name = "a64fx",
146 .flatten = true,
147 },
148 .{
149 .llvm_name = "a65",
150 .flatten = true,
151 },
152 .{
153 .llvm_name = "a72",
154 .flatten = true,
155 },
156 .{
157 .llvm_name = "a73",
158 .flatten = true,
159 },
160 .{
161 .llvm_name = "a75",
162 .flatten = true,
163 },
164 .{
165 .llvm_name = "a76",
166 .flatten = true,
167 },
168 .{
169 .llvm_name = "a77",
170 .flatten = true,
171 },
172 .{
173 .llvm_name = "a78",
174 .flatten = true,
175 },
176 .{
177 .llvm_name = "a78ae",
178 .flatten = true,
179 },
180 .{
181 .llvm_name = "a78c",
182 .flatten = true,
183 },
184 .{
185 .llvm_name = "a710",
186 .flatten = true,
187 },
188 .{
189 .llvm_name = "a715",
190 .flatten = true,
191 },
192 .{
193 .llvm_name = "a720",
194 .flatten = true,
195 },
196 .{
197 .llvm_name = "a720ae",
198 .flatten = true,
199 },
200 .{
201 .llvm_name = "ampere1a",
202 .flatten = true,
203 },
204 .{
205 .llvm_name = "apple-a7",
206 .flatten = true,
207 },
208 .{
209 .llvm_name = "apple-a10",
210 .flatten = true,
211 },
212 .{
213 .llvm_name = "apple-a11",
214 .flatten = true,
215 },
216 .{
217 .llvm_name = "apple-a12",
218 .flatten = true,
219 },
220 .{
221 .llvm_name = "apple-a13",
222 .flatten = true,
223 },
224 .{
225 .llvm_name = "apple-a14",
226 .flatten = true,
227 },
228 .{
229 .llvm_name = "apple-a15",
230 .flatten = true,
231 },
232 .{
233 .llvm_name = "apple-a16",
234 .flatten = true,
235 },
236 .{
237 .llvm_name = "apple-a17",
238 .flatten = true,
239 },
240 .{
241 .llvm_name = "apple-a7-sysreg",
242 .flatten = true,
243 },
244 .{
245 .llvm_name = "apple-m4",
246 .flatten = true,
247 },
248 .{
249 .llvm_name = "carmel",
250 .flatten = true,
251 },
252 .{
253 .llvm_name = "cortex-a725",
254 .flatten = true,
255 },
256 .{
257 .llvm_name = "cortex-a78",
258 .flatten = true,
259 },
260 .{
261 .llvm_name = "cortex-r82",
262 .flatten = true,
263 },
264 .{
265 .llvm_name = "cortex-r82ae",
266 .flatten = true,
267 },
268 .{
269 .llvm_name = "cortex-x1",
270 .flatten = true,
271 },
272 .{
273 .llvm_name = "cortex-x2",
274 .flatten = true,
275 },
276 .{
277 .llvm_name = "cortex-x3",
278 .flatten = true,
279 },
280 .{
281 .llvm_name = "cortex-x4",
282 .flatten = true,
283 },
284 .{
285 .llvm_name = "cortex-x925",
286 .flatten = true,
287 },
288 .{
289 .llvm_name = "falkor",
290 .flatten = true,
291 },
292 .{
293 .llvm_name = "kryo",
294 .flatten = true,
295 },
296 .{
297 .llvm_name = "saphira",
298 .flatten = true,
299 },
300 .{
301 .llvm_name = "thunderx",
302 .flatten = true,
303 },
304 .{
305 .llvm_name = "thunderx2t99",
306 .flatten = true,
307 },
308 .{
309 .llvm_name = "thunderx3t110",
310 .flatten = true,
311 },
312 .{
313 .llvm_name = "thunderxt81",
314 .flatten = true,
315 },
316 .{
317 .llvm_name = "thunderxt83",
318 .flatten = true,
319 },
320 .{
321 .llvm_name = "thunderxt88",
322 .flatten = true,
323 },
324 .{
325 .llvm_name = "tsv110",
326 .flatten = true,
327 },
328 .{
329 .llvm_name = "ampere1",
330 .flatten = true,
331 },
332 .{
333 .llvm_name = "ampere1b",
334 .flatten = true,
335 },
336 },
337 .extra_cpus = &.{
338 .{
339 .llvm_name = null,
340 .zig_name = "exynos_m1",
341 .features = &.{
342 "crc",
343 "crypto",
344 "exynos_cheap_as_move",
345 "force_32bit_jump_tables",
346 "fuse_aes",
347 "perfmon",
348 "slow_misaligned_128store",
349 "slow_paired_128",
350 "use_postra_scheduler",
351 "use_reciprocal_square_root",
352 "v8a",
353 },
354 },
355 .{
356 .llvm_name = null,
357 .zig_name = "exynos_m2",
358 .features = &.{
359 "crc",
360 "crypto",
361 "exynos_cheap_as_move",
362 "force_32bit_jump_tables",
363 "fuse_aes",
364 "perfmon",
365 "slow_misaligned_128store",
366 "slow_paired_128",
367 "use_postra_scheduler",
368 "v8a",
369 },
370 },
371 .{
372 .llvm_name = null,
373 .zig_name = "xgene1",
374 .features = &.{
375 "perfmon",
376 "v8a",
377 },
378 },
379 .{
380 .llvm_name = null,
381 .zig_name = "emag",
382 .features = &.{
383 "crc",
384 "crypto",
385 "perfmon",
386 "v8a",
387 },
388 },
389 },
390 .omit_cpus = &.{
391 // Who thought this alias was a good idea? Upgrade your compiler and suddenly your
392 // programs SIGILL because this changed meaning. Brilliant.
393 "apple-latest",
394 },
395 },
396 .{
397 .zig_name = "alpha",
398 .llvm = null,
399 .extra_features = &.{
400 .{
401 .zig_name = "bwx",
402 .desc = "Enable byte/word extensions",
403 .deps = &.{},
404 },
405 .{
406 .zig_name = "cix",
407 .desc = "Enable counting extensions",
408 .deps = &.{},
409 },
410 .{
411 .zig_name = "fix",
412 .desc = "Enable floating point move and square root extensions",
413 .deps = &.{},
414 },
415 .{
416 .zig_name = "max",
417 .desc = "Enable motion video extensions",
418 .deps = &.{},
419 },
420 },
421 .extra_cpus = &.{
422 .{
423 .llvm_name = null,
424 .zig_name = "ev4",
425 .features = &.{},
426 },
427 .{
428 .llvm_name = null,
429 .zig_name = "ev45",
430 .features = &.{},
431 },
432 .{
433 .llvm_name = null,
434 .zig_name = "ev5",
435 .features = &.{},
436 },
437 .{
438 .llvm_name = null,
439 .zig_name = "ev56",
440 .features = &.{
441 "bwx",
442 },
443 },
444 .{
445 .llvm_name = null,
446 .zig_name = "pca56",
447 .features = &.{
448 "bwx",
449 "max",
450 },
451 },
452 .{
453 .llvm_name = null,
454 .zig_name = "ev6",
455 .features = &.{
456 "bwx",
457 "fix",
458 "max",
459 },
460 },
461 .{
462 .llvm_name = null,
463 .zig_name = "ev67",
464 .features = &.{
465 "bwx",
466 "cix",
467 "fix",
468 "max",
469 },
470 },
471 },
472 },
473 .{
474 .zig_name = "amdgcn",
475 .llvm = .{
476 .name = "AMDGPU",
477 .td_name = "AMDGPU",
478 },
479 .branch_quota = 2000,
480 .feature_overrides = &.{
481 .{
482 .llvm_name = "DumpCode",
483 .omit = true,
484 },
485 .{
486 .llvm_name = "dumpcode",
487 .omit = true,
488 },
489 .{
490 .llvm_name = "enable-ds128",
491 .zig_name = "ds128",
492 },
493 .{
494 .llvm_name = "enable-flat-scratch",
495 .zig_name = "flat_scratch",
496 },
497 .{
498 .llvm_name = "enable-prt-strict-null",
499 .zig_name = "prt_strict_null",
500 },
501 },
502 },
503 .{
504 .zig_name = "arc",
505 .llvm = .{
506 .name = "ARC",
507 .td_name = "ARC",
508 },
509 },
510 .{
511 .zig_name = "arm",
512 .llvm = .{
513 .name = "ARM",
514 .td_name = "ARM",
515 },
516 .branch_quota = 10000,
517 .feature_overrides = &.{
518 .{
519 .llvm_name = "exynos",
520 .flatten = true,
521 },
522 .{
523 .llvm_name = "cortex-a78",
524 .flatten = true,
525 },
526 .{
527 .llvm_name = "cortex-a78ae",
528 .flatten = true,
529 },
530 .{
531 .llvm_name = "cortex-a710",
532 .flatten = true,
533 },
534 .{
535 .llvm_name = "cortex-m4",
536 .omit_deps = &.{"vfp4d16sp"},
537 },
538 .{
539 .llvm_name = "cortex-m7",
540 .omit_deps = &.{"fp_armv8d16"},
541 },
542 .{
543 .llvm_name = "cortex-m33",
544 .omit_deps = &.{ "fp_armv8d16sp", "dsp" },
545 },
546 .{
547 .llvm_name = "cortex-m35p",
548 .omit_deps = &.{ "fp_armv8d16sp", "dsp" },
549 },
550 .{
551 .llvm_name = "cortex-m55",
552 .omit_deps = &.{ "mve_fp", "fp_armv8d16" },
553 },
554 .{
555 .llvm_name = "cortex-m85",
556 .omit_deps = &.{ "mve_fp", "pacbti", "fp_armv8d16" },
557 },
558 .{
559 .llvm_name = "cortex-x1c",
560 .flatten = true,
561 },
562 .{
563 .llvm_name = "r4",
564 .flatten = true,
565 },
566 .{
567 .llvm_name = "r52plus",
568 .flatten = true,
569 },
570 .{
571 .llvm_name = "r5",
572 .flatten = true,
573 },
574 .{
575 .llvm_name = "r52",
576 .flatten = true,
577 },
578 .{
579 .llvm_name = "r7",
580 .flatten = true,
581 },
582 .{
583 .llvm_name = "m3",
584 .flatten = true,
585 },
586 .{
587 .llvm_name = "m7",
588 .flatten = true,
589 },
590 .{
591 .llvm_name = "krait",
592 .flatten = true,
593 },
594 .{
595 .llvm_name = "kryo",
596 .flatten = true,
597 },
598 .{
599 .llvm_name = "swift",
600 .flatten = true,
601 },
602 .{
603 .llvm_name = "cortex-x1",
604 .flatten = true,
605 },
606 .{
607 .llvm_name = "neoverse-v1",
608 .flatten = true,
609 },
610 .{
611 .llvm_name = "a5",
612 .flatten = true,
613 },
614 .{
615 .llvm_name = "a7",
616 .flatten = true,
617 },
618 .{
619 .llvm_name = "a8",
620 .flatten = true,
621 },
622 .{
623 .llvm_name = "a9",
624 .flatten = true,
625 },
626 .{
627 .llvm_name = "a12",
628 .flatten = true,
629 },
630 .{
631 .llvm_name = "a15",
632 .flatten = true,
633 },
634 .{
635 .llvm_name = "a17",
636 .flatten = true,
637 },
638 .{
639 .llvm_name = "a32",
640 .flatten = true,
641 },
642 .{
643 .llvm_name = "a35",
644 .flatten = true,
645 },
646 .{
647 .llvm_name = "a53",
648 .flatten = true,
649 },
650 .{
651 .llvm_name = "a55",
652 .flatten = true,
653 },
654 .{
655 .llvm_name = "a57",
656 .flatten = true,
657 },
658 .{
659 .llvm_name = "a72",
660 .flatten = true,
661 },
662 .{
663 .llvm_name = "a73",
664 .flatten = true,
665 },
666 .{
667 .llvm_name = "a75",
668 .flatten = true,
669 },
670 .{
671 .llvm_name = "a76",
672 .flatten = true,
673 },
674 .{
675 .llvm_name = "a77",
676 .flatten = true,
677 },
678 .{
679 .llvm_name = "a78c",
680 .flatten = true,
681 },
682 .{
683 .llvm_name = "armv2",
684 .zig_name = "v2",
685 .extra_deps = &.{"strict_align"},
686 },
687 .{
688 .llvm_name = "armv2a",
689 .zig_name = "v2a",
690 .extra_deps = &.{"strict_align"},
691 },
692 .{
693 .llvm_name = "armv3",
694 .zig_name = "v3",
695 .extra_deps = &.{"strict_align"},
696 },
697 .{
698 .llvm_name = "armv3m",
699 .zig_name = "v3m",
700 .extra_deps = &.{"strict_align"},
701 },
702 .{
703 .llvm_name = "armv4",
704 .zig_name = "v4",
705 .extra_deps = &.{"strict_align"},
706 },
707 .{
708 .llvm_name = "armv4t",
709 .zig_name = "v4t",
710 .extra_deps = &.{"strict_align"},
711 },
712 .{
713 .llvm_name = "armv5t",
714 .zig_name = "v5t",
715 .extra_deps = &.{"strict_align"},
716 },
717 .{
718 .llvm_name = "armv5te",
719 .zig_name = "v5te",
720 .extra_deps = &.{"strict_align"},
721 },
722 .{
723 .llvm_name = "armv5tej",
724 .zig_name = "v5tej",
725 .extra_deps = &.{"strict_align"},
726 },
727 .{
728 .llvm_name = "armv6",
729 .zig_name = "v6",
730 },
731 .{
732 .llvm_name = "armv6-m",
733 .zig_name = "v6m",
734 },
735 .{
736 .llvm_name = "armv6j",
737 .zig_name = "v6j",
738 },
739 .{
740 .llvm_name = "armv6k",
741 .zig_name = "v6k",
742 },
743 .{
744 .llvm_name = "armv6kz",
745 .zig_name = "v6kz",
746 },
747 .{
748 .llvm_name = "armv6s-m",
749 .zig_name = "v6sm",
750 },
751 .{
752 .llvm_name = "armv6t2",
753 .zig_name = "v6t2",
754 },
755 .{
756 .llvm_name = "armv7-a",
757 .zig_name = "v7a",
758 },
759 .{
760 .llvm_name = "armv7-m",
761 .zig_name = "v7m",
762 },
763 .{
764 .llvm_name = "armv7-r",
765 .zig_name = "v7r",
766 },
767 .{
768 .llvm_name = "armv7e-m",
769 .zig_name = "v7em",
770 },
771 .{
772 .llvm_name = "armv7k",
773 .omit = true,
774 },
775 .{
776 .llvm_name = "armv7s",
777 .omit = true,
778 },
779 .{
780 .llvm_name = "armv7ve",
781 .zig_name = "v7ve",
782 },
783 .{
784 .llvm_name = "armv8.1-a",
785 .zig_name = "v8_1a",
786 },
787 .{
788 .llvm_name = "armv8.1-m.main",
789 .zig_name = "v8_1m_main",
790 },
791 .{
792 .llvm_name = "armv8.2-a",
793 .zig_name = "v8_2a",
794 },
795 .{
796 .llvm_name = "armv8.3-a",
797 .zig_name = "v8_3a",
798 },
799 .{
800 .llvm_name = "armv8.4-a",
801 .zig_name = "v8_4a",
802 },
803 .{
804 .llvm_name = "armv8.5-a",
805 .zig_name = "v8_5a",
806 },
807 .{
808 .llvm_name = "armv8.6-a",
809 .zig_name = "v8_6a",
810 },
811 .{
812 .llvm_name = "armv8.7-a",
813 .zig_name = "v8_7a",
814 },
815 .{
816 .llvm_name = "armv8.8-a",
817 .zig_name = "v8_8a",
818 },
819 .{
820 .llvm_name = "armv8.9-a",
821 .zig_name = "v8_9a",
822 },
823 .{
824 .llvm_name = "armv8-a",
825 .zig_name = "v8a",
826 },
827 .{
828 .llvm_name = "armv8-m.base",
829 .zig_name = "v8m",
830 },
831 .{
832 .llvm_name = "armv8-m.main",
833 .zig_name = "v8m_main",
834 },
835 .{
836 .llvm_name = "armv8-r",
837 .zig_name = "v8r",
838 },
839 .{
840 .llvm_name = "armv9.1-a",
841 .zig_name = "v9_1a",
842 },
843 .{
844 .llvm_name = "armv9.2-a",
845 .zig_name = "v9_2a",
846 },
847 .{
848 .llvm_name = "armv9.3-a",
849 .zig_name = "v9_3a",
850 },
851 .{
852 .llvm_name = "armv9.4-a",
853 .zig_name = "v9_4a",
854 },
855 .{
856 .llvm_name = "armv9.5-a",
857 .zig_name = "v9_5a",
858 },
859 .{
860 .llvm_name = "armv9.6-a",
861 .zig_name = "v9_6a",
862 },
863 .{
864 .llvm_name = "armv9-a",
865 .zig_name = "v9a",
866 },
867 .{
868 .llvm_name = "v4t",
869 .zig_name = "has_v4t",
870 },
871 .{
872 .llvm_name = "v5t",
873 .zig_name = "has_v5t",
874 },
875 .{
876 .llvm_name = "v5te",
877 .zig_name = "has_v5te",
878 },
879 .{
880 .llvm_name = "v6",
881 .zig_name = "has_v6",
882 },
883 .{
884 .llvm_name = "v6k",
885 .zig_name = "has_v6k",
886 },
887 .{
888 .llvm_name = "v6m",
889 .zig_name = "has_v6m",
890 },
891 .{
892 .llvm_name = "v6t2",
893 .zig_name = "has_v6t2",
894 },
895 .{
896 .llvm_name = "v7",
897 .zig_name = "has_v7",
898 },
899 .{
900 .llvm_name = "v7clrex",
901 .zig_name = "has_v7clrex",
902 },
903 .{
904 .llvm_name = "v8",
905 .zig_name = "has_v8",
906 },
907 .{
908 .llvm_name = "v8m",
909 .zig_name = "has_v8m",
910 },
911 .{
912 .llvm_name = "v8m.main",
913 .zig_name = "has_v8m_main",
914 },
915 .{
916 .llvm_name = "v8.1a",
917 .zig_name = "has_v8_1a",
918 },
919 .{
920 .llvm_name = "v8.1m.main",
921 .zig_name = "has_v8_1m_main",
922 },
923 .{
924 .llvm_name = "v8.2a",
925 .zig_name = "has_v8_2a",
926 },
927 .{
928 .llvm_name = "v8.3a",
929 .zig_name = "has_v8_3a",
930 },
931 .{
932 .llvm_name = "v8.4a",
933 .zig_name = "has_v8_4a",
934 },
935 .{
936 .llvm_name = "v8.5a",
937 .zig_name = "has_v8_5a",
938 },
939 .{
940 .llvm_name = "v8.6a",
941 .zig_name = "has_v8_6a",
942 },
943 .{
944 .llvm_name = "v8.7a",
945 .zig_name = "has_v8_7a",
946 },
947 .{
948 .llvm_name = "v8.8a",
949 .zig_name = "has_v8_8a",
950 },
951 .{
952 .llvm_name = "v8.9a",
953 .zig_name = "has_v8_9a",
954 },
955 .{
956 .llvm_name = "v9a",
957 .zig_name = "has_v9a",
958 },
959 .{
960 .llvm_name = "v9.1a",
961 .zig_name = "has_v9_1a",
962 },
963 .{
964 .llvm_name = "v9.2a",
965 .zig_name = "has_v9_2a",
966 },
967 .{
968 .llvm_name = "v9.3a",
969 .zig_name = "has_v9_3a",
970 },
971 .{
972 .llvm_name = "v9.4a",
973 .zig_name = "has_v9_4a",
974 },
975 .{
976 .llvm_name = "v9.5a",
977 .zig_name = "has_v9_5a",
978 },
979 .{
980 .llvm_name = "v9.6a",
981 .zig_name = "has_v9_6a",
982 },
983 },
984 .extra_cpus = &.{
985 .{
986 .llvm_name = "generic",
987 .zig_name = "baseline",
988 .features = &.{"v7a"},
989 },
990 .{
991 .llvm_name = null,
992 .zig_name = "exynos_m1",
993 .features = &.{ "v8a", "exynos" },
994 },
995 .{
996 .llvm_name = null,
997 .zig_name = "exynos_m2",
998 .features = &.{ "v8a", "exynos" },
999 },
1000 },
1001 .extra_features = &.{
1002 // LLVM removed support for v2 and v3 but zig wants to support targeting old hardware
1003 .{
1004 .zig_name = "v2",
1005 .desc = "ARMv2 architecture",
1006 .deps = &.{"strict_align"},
1007 },
1008 .{
1009 .zig_name = "v2a",
1010 .desc = "ARMv2a architecture",
1011 .deps = &.{"strict_align"},
1012 },
1013 .{
1014 .zig_name = "v3",
1015 .desc = "ARMv3 architecture",
1016 .deps = &.{"strict_align"},
1017 },
1018 .{
1019 .zig_name = "v3m",
1020 .desc = "ARMv3m architecture",
1021 .deps = &.{"strict_align"},
1022 },
1023 },
1024 },
1025 .{
1026 .zig_name = "avr",
1027 .llvm = .{
1028 .name = "AVR",
1029 .td_name = "AVR",
1030 },
1031 },
1032 .{
1033 .zig_name = "bpf",
1034 .llvm = .{
1035 .name = "BPF",
1036 .td_name = "BPF",
1037 },
1038 },
1039 .{
1040 .zig_name = "csky",
1041 .llvm = .{
1042 .name = "CSKY",
1043 .td_name = "CSKY",
1044 },
1045 },
1046 .{
1047 .zig_name = "hexagon",
1048 .llvm = .{
1049 .name = "Hexagon",
1050 .td_name = "Hexagon",
1051 },
1052 },
1053 .{
1054 .zig_name = "hppa",
1055 .llvm = null,
1056 .extra_features = &.{
1057 .{
1058 .zig_name = "64bit",
1059 .desc = "Enable 64-bit PA-RISC 2.0",
1060 .deps = &.{"v2_0"},
1061 },
1062 .{
1063 .zig_name = "max_1",
1064 .desc = "Enable MAX-1 multimedia acceleration extensions",
1065 .deps = &.{},
1066 },
1067 .{
1068 .zig_name = "max_2",
1069 .desc = "Enable MAX-2 multimedia acceleration extensions",
1070 .deps = &.{"max_1"},
1071 },
1072 .{
1073 .zig_name = "v1_1",
1074 .desc = "Enable ISA v1.1",
1075 .deps = &.{},
1076 },
1077 .{
1078 .zig_name = "v2_0",
1079 .desc = "Enable ISA v2.0",
1080 .deps = &.{ "max_2", "v1_1" },
1081 },
1082 },
1083 .extra_cpus = &.{
1084 .{
1085 .llvm_name = null,
1086 .zig_name = "ts_1",
1087 .features = &.{},
1088 },
1089 .{
1090 .llvm_name = null,
1091 .zig_name = "ns_1",
1092 .features = &.{},
1093 },
1094 .{
1095 .llvm_name = null,
1096 .zig_name = "ns_2",
1097 .features = &.{},
1098 },
1099 .{
1100 .llvm_name = null,
1101 .zig_name = "pcx",
1102 .features = &.{},
1103 },
1104 .{
1105 .llvm_name = null,
1106 .zig_name = "pa_7000",
1107 .features = &.{
1108 "v1_1",
1109 },
1110 },
1111 .{
1112 .llvm_name = null,
1113 .zig_name = "pa_7100",
1114 .features = &.{
1115 "v1_1",
1116 },
1117 },
1118 .{
1119 .llvm_name = null,
1120 .zig_name = "pa_7150",
1121 .features = &.{
1122 "v1_1",
1123 },
1124 },
1125 .{
1126 .llvm_name = null,
1127 .zig_name = "pa_7100lc",
1128 .features = &.{
1129 "max_1",
1130 "v1_1",
1131 },
1132 },
1133 .{
1134 .llvm_name = null,
1135 .zig_name = "pa_7200",
1136 .features = &.{
1137 "v1_1",
1138 },
1139 },
1140 .{
1141 .llvm_name = null,
1142 .zig_name = "pa_7300lc",
1143 .features = &.{
1144 "max_1",
1145 "v1_1",
1146 },
1147 },
1148 .{
1149 .llvm_name = null,
1150 .zig_name = "pa_8000",
1151 .features = &.{
1152 "64bit",
1153 },
1154 },
1155 .{
1156 .llvm_name = null,
1157 .zig_name = "pa_8200",
1158 .features = &.{
1159 "64bit",
1160 },
1161 },
1162 .{
1163 .llvm_name = null,
1164 .zig_name = "pa_8500",
1165 .features = &.{
1166 "64bit",
1167 },
1168 },
1169 .{
1170 .llvm_name = null,
1171 .zig_name = "pa_8600",
1172 .features = &.{
1173 "64bit",
1174 },
1175 },
1176 .{
1177 .llvm_name = null,
1178 .zig_name = "pa_8700",
1179 .features = &.{
1180 "64bit",
1181 },
1182 },
1183 .{
1184 .llvm_name = null,
1185 .zig_name = "pa_8800",
1186 .features = &.{
1187 "64bit",
1188 },
1189 },
1190 .{
1191 .llvm_name = null,
1192 .zig_name = "pa_8900",
1193 .features = &.{
1194 "64bit",
1195 },
1196 },
1197 },
1198 },
1199 .{
1200 .zig_name = "kvx",
1201 .llvm = null,
1202 .extra_features = &.{
1203 .{
1204 .zig_name = "v3_1",
1205 .desc = "Enable ISA v3.1",
1206 .deps = &.{},
1207 },
1208 .{
1209 .zig_name = "v3_2",
1210 .desc = "Enable ISA v3.2",
1211 .deps = &.{"v3_1"},
1212 },
1213 .{
1214 .zig_name = "v4_1",
1215 .desc = "Enable ISA v4.1",
1216 .deps = &.{"v3_2"},
1217 },
1218 },
1219 .extra_cpus = &.{
1220 .{
1221 .llvm_name = null,
1222 .zig_name = "coolidge_v1",
1223 .features = &.{
1224 "v3_1",
1225 },
1226 },
1227 .{
1228 .llvm_name = null,
1229 .zig_name = "coolidge_v2",
1230 .features = &.{
1231 "v3_2",
1232 },
1233 },
1234 },
1235 },
1236 .{
1237 .zig_name = "lanai",
1238 .llvm = .{
1239 .name = "Lanai",
1240 .td_name = "Lanai",
1241 },
1242 },
1243 .{
1244 .zig_name = "loongarch",
1245 .llvm = .{
1246 .name = "LoongArch",
1247 .td_name = "LoongArch",
1248 },
1249 .extra_cpus = &.{
1250 .{
1251 .llvm_name = null,
1252 .zig_name = "la64v1_0",
1253 .features = &.{
1254 "64bit",
1255 "lsx",
1256 "ual",
1257 },
1258 },
1259 .{
1260 .llvm_name = null,
1261 .zig_name = "la64v1_1",
1262 .features = &.{
1263 "64bit",
1264 "div32",
1265 "frecipe",
1266 "lam_bh",
1267 "lamcas",
1268 "ld_seq_sa",
1269 "lsx",
1270 "scq",
1271 "ual",
1272 },
1273 },
1274 },
1275 .omit_cpus = &.{
1276 "generic",
1277 "loongarch64",
1278 },
1279 },
1280 .{
1281 .zig_name = "m68k",
1282 .llvm = .{
1283 .name = "M68k",
1284 .td_name = "M68k",
1285 },
1286 },
1287 .{
1288 .zig_name = "msp430",
1289 .llvm = .{
1290 .name = "MSP430",
1291 .td_name = "MSP430",
1292 },
1293 },
1294 .{
1295 .zig_name = "mips",
1296 .llvm = .{
1297 .name = "Mips",
1298 .td_name = "Mips",
1299 },
1300 },
1301 .{
1302 .zig_name = "nvptx",
1303 .llvm = .{
1304 .name = "NVPTX",
1305 .td_name = "NVPTX",
1306 },
1307 },
1308 .{
1309 .zig_name = "powerpc",
1310 .llvm = .{
1311 .name = "PowerPC",
1312 .td_name = "PPC",
1313 },
1314 .feature_overrides = &.{
1315 .{
1316 .llvm_name = "aix",
1317 .omit = true,
1318 },
1319 .{
1320 .llvm_name = "aix-shared-lib-tls-model-opt",
1321 .omit = true,
1322 },
1323 .{
1324 .llvm_name = "aix-small-local-dynamic-tls",
1325 .omit = true,
1326 },
1327 .{
1328 .llvm_name = "aix-small-local-exec-tls",
1329 .omit = true,
1330 },
1331 .{
1332 .llvm_name = "modern-aix-as",
1333 .omit = true,
1334 },
1335 },
1336 .omit_cpus = &.{
1337 "ppc32",
1338 },
1339 },
1340 .{
1341 .zig_name = "propeller",
1342 .llvm = null,
1343 .extra_features = &.{
1344 .{
1345 .zig_name = "p2",
1346 .desc = "Enable Propeller 2",
1347 .deps = &.{},
1348 },
1349 },
1350 .extra_cpus = &.{
1351 .{
1352 .llvm_name = null,
1353 .zig_name = "p1",
1354 .features = &.{},
1355 },
1356 .{
1357 .llvm_name = null,
1358 .zig_name = "p2",
1359 .features = &.{"p2"},
1360 },
1361 },
1362 },
1363 .{
1364 .zig_name = "spirv",
1365 .llvm = .{
1366 .name = "SPIRV",
1367 .td_name = "SPIRV",
1368 },
1369 .branch_quota = 2000,
1370 .extra_features = &.{
1371 .{
1372 .zig_name = "v1_0",
1373 .desc = "Enable version 1.0",
1374 .deps = &.{},
1375 },
1376 .{
1377 .zig_name = "v1_1",
1378 .desc = "Enable version 1.1",
1379 .deps = &.{"v1_0"},
1380 },
1381 .{
1382 .zig_name = "v1_2",
1383 .desc = "Enable version 1.2",
1384 .deps = &.{"v1_1"},
1385 },
1386 .{
1387 .zig_name = "v1_3",
1388 .desc = "Enable version 1.3",
1389 .deps = &.{"v1_2"},
1390 },
1391 .{
1392 .zig_name = "v1_4",
1393 .desc = "Enable version 1.4",
1394 .deps = &.{"v1_3"},
1395 },
1396 .{
1397 .zig_name = "v1_5",
1398 .desc = "Enable version 1.5",
1399 .deps = &.{"v1_4"},
1400 },
1401 .{
1402 .zig_name = "v1_6",
1403 .desc = "Enable version 1.6",
1404 .deps = &.{"v1_5"},
1405 },
1406 .{
1407 .zig_name = "int64",
1408 .desc = "Enable Int64 capability",
1409 .deps = &.{"v1_0"},
1410 },
1411 .{
1412 .zig_name = "float16",
1413 .desc = "Enable Float16 capability",
1414 .deps = &.{"v1_0"},
1415 },
1416 .{
1417 .zig_name = "float64",
1418 .desc = "Enable Float64 capability",
1419 .deps = &.{"v1_0"},
1420 },
1421 .{
1422 .zig_name = "storage_push_constant16",
1423 .desc = "Enable SPV_KHR_16bit_storage extension and the StoragePushConstant16 capability",
1424 .deps = &.{"v1_3"},
1425 },
1426 .{
1427 .zig_name = "arbitrary_precision_integers",
1428 .desc = "Enable SPV_INTEL_arbitrary_precision_integers extension and the ArbitraryPrecisionIntegersINTEL capability",
1429 .deps = &.{"v1_5"},
1430 },
1431 .{
1432 .zig_name = "generic_pointer",
1433 .desc = "Enable GenericPointer capability",
1434 .deps = &.{"v1_0"},
1435 },
1436 .{
1437 .zig_name = "vector16",
1438 .desc = "Enable Vector16 capability",
1439 .deps = &.{"v1_0"},
1440 },
1441 .{
1442 .zig_name = "variable_pointers",
1443 .desc = "Enable SPV_KHR_physical_storage_buffer extension and the PhysicalStorageBufferAddresses capability",
1444 .deps = &.{"v1_0"},
1445 },
1446 },
1447 .extra_cpus = &.{
1448 .{
1449 .llvm_name = null,
1450 .zig_name = "vulkan_v1_2",
1451 .features = &.{"v1_5"},
1452 },
1453 .{
1454 .llvm_name = null,
1455 .zig_name = "opencl_v2",
1456 .features = &.{"v1_2"},
1457 },
1458 },
1459 },
1460 .{
1461 .zig_name = "riscv",
1462 .llvm = .{
1463 .name = "RISCV",
1464 .td_name = "RISCV",
1465 },
1466 .branch_quota = 2000,
1467 .feature_overrides = &.{
1468 .{
1469 .llvm_name = "sifive7",
1470 .flatten = true,
1471 },
1472 },
1473 .extra_cpus = &.{
1474 .{
1475 .llvm_name = null,
1476 .zig_name = "baseline_rv32",
1477 .features = &.{ "32bit", "a", "c", "d", "f", "i", "m" },
1478 },
1479 .{
1480 .llvm_name = null,
1481 .zig_name = "baseline_rv64",
1482 .features = &.{ "64bit", "a", "c", "d", "f", "i", "m" },
1483 },
1484 },
1485 },
1486 .{
1487 .zig_name = "sparc",
1488 .llvm = .{
1489 .name = "Sparc",
1490 .td_name = "Sparc",
1491 },
1492 },
1493 .{
1494 .zig_name = "s390x",
1495 .llvm = .{
1496 .name = "SystemZ",
1497 .td_name = "SystemZ",
1498 },
1499 },
1500 .{
1501 .zig_name = "ve",
1502 .llvm = .{
1503 .name = "VE",
1504 .td_name = "VE",
1505 },
1506 },
1507 .{
1508 .zig_name = "wasm",
1509 .llvm = .{
1510 .name = "WebAssembly",
1511 .td_name = "WebAssembly",
1512 },
1513 // For whatever reason, LLVM's WebAssembly backend sets these implied features in code
1514 // rather than making them proper dependencies, so fix that here...
1515 .feature_overrides = &.{
1516 .{
1517 .llvm_name = "bulk-memory",
1518 .extra_deps = &.{"bulk_memory_opt"},
1519 },
1520 .{
1521 .llvm_name = "reference-types",
1522 .extra_deps = &.{"call_indirect_overlong"},
1523 },
1524 },
1525 .extra_features = &.{
1526 .{
1527 .zig_name = "nontrapping_bulk_memory_len0",
1528 .desc = "Bulk memory operations with a zero length do not trap",
1529 .deps = &.{"bulk_memory_opt"},
1530 },
1531 },
1532 },
1533 .{
1534 .zig_name = "x86",
1535 .llvm = .{
1536 .name = "X86",
1537 .td_name = "X86",
1538 },
1539 .feature_overrides = &.{
1540 .{
1541 .llvm_name = "64bit-mode",
1542 .omit = true,
1543 },
1544 // Remove these when LLVM removes AVX10.N-256 support.
1545 .{
1546 .llvm_name = "avx10.1-256",
1547 .flatten = true,
1548 },
1549 .{
1550 .llvm_name = "avx10.2-256",
1551 .flatten = true,
1552 },
1553 .{
1554 .llvm_name = "avx10.1-512",
1555 .zig_name = "avx10_1",
1556 },
1557 .{
1558 .llvm_name = "avx10.2-512",
1559 .zig_name = "avx10_2",
1560 },
1561 .{
1562 .llvm_name = "avx512f",
1563 .extra_deps = &.{"evex512"},
1564 },
1565 .{
1566 .llvm_name = "alderlake",
1567 .extra_deps = &.{ "smap", "smep" },
1568 },
1569 .{
1570 .llvm_name = "amdfam10",
1571 .extra_deps = &.{"3dnowa"},
1572 },
1573 .{
1574 .llvm_name = "arrowlake",
1575 .extra_deps = &.{ "smap", "smep" },
1576 },
1577 .{
1578 .llvm_name = "arrowlake-s",
1579 .extra_deps = &.{ "smap", "smep" },
1580 },
1581 .{
1582 .llvm_name = "athlon",
1583 .extra_deps = &.{"3dnowa"},
1584 },
1585 .{
1586 .llvm_name = "athlon64",
1587 .extra_deps = &.{"3dnowa"},
1588 },
1589 .{
1590 .llvm_name = "athlon64-sse3",
1591 .extra_deps = &.{"3dnowa"},
1592 },
1593 .{
1594 .llvm_name = "athlon-4",
1595 .extra_deps = &.{"3dnowa"},
1596 },
1597 .{
1598 .llvm_name = "athlon-fx",
1599 .extra_deps = &.{"3dnowa"},
1600 },
1601 .{
1602 .llvm_name = "athlon-mp",
1603 .extra_deps = &.{"3dnowa"},
1604 },
1605 .{
1606 .llvm_name = "athlon-tbird",
1607 .extra_deps = &.{"3dnowa"},
1608 },
1609 .{
1610 .llvm_name = "athlon-xp",
1611 .extra_deps = &.{"3dnowa"},
1612 },
1613 .{
1614 .llvm_name = "barcelona",
1615 .extra_deps = &.{ "3dnowa", "smap", "smep" },
1616 },
1617 .{
1618 .llvm_name = "broadwell",
1619 .extra_deps = &.{ "smap", "smep" },
1620 },
1621 .{
1622 .llvm_name = "c3",
1623 .extra_deps = &.{"3dnow"},
1624 },
1625 .{
1626 .llvm_name = "cannonlake",
1627 .extra_deps = &.{ "smap", "smep" },
1628 },
1629 .{
1630 .llvm_name = "cascadelake",
1631 .extra_deps = &.{ "smap", "smep" },
1632 },
1633 .{
1634 .llvm_name = "emeraldrapids",
1635 .extra_deps = &.{ "smap", "smep" },
1636 },
1637 .{
1638 .llvm_name = "geode",
1639 .extra_deps = &.{"3dnowa"},
1640 },
1641 .{
1642 .llvm_name = "goldmont",
1643 .extra_deps = &.{ "smap", "smep" },
1644 },
1645 .{
1646 .llvm_name = "goldmont_plus",
1647 .extra_deps = &.{ "smap", "smep" },
1648 },
1649 .{
1650 .llvm_name = "haswell",
1651 .extra_deps = &.{"smep"},
1652 },
1653 .{
1654 .llvm_name = "i386",
1655 .extra_deps = &.{"bsf_bsr_0_clobbers_result"},
1656 },
1657 .{
1658 .llvm_name = "i486",
1659 .extra_deps = &.{"bsf_bsr_0_clobbers_result"},
1660 },
1661 .{
1662 .llvm_name = "icelake_client",
1663 .extra_deps = &.{ "smap", "smep" },
1664 },
1665 .{
1666 .llvm_name = "icelake_server",
1667 .extra_deps = &.{ "smap", "smep" },
1668 },
1669 .{
1670 .llvm_name = "ivybridge",
1671 .extra_deps = &.{"smep"},
1672 },
1673 .{
1674 .llvm_name = "k6-2",
1675 .extra_deps = &.{"3dnow"},
1676 },
1677 .{
1678 .llvm_name = "k6-3",
1679 .extra_deps = &.{"3dnow"},
1680 },
1681 .{
1682 .llvm_name = "k8",
1683 .extra_deps = &.{"3dnowa"},
1684 },
1685 .{
1686 .llvm_name = "k8-sse3",
1687 .extra_deps = &.{"3dnowa"},
1688 },
1689 .{
1690 .llvm_name = "knl",
1691 .extra_deps = &.{
1692 "avx512er",
1693 "avx512pf",
1694 "prefetchwt1",
1695 },
1696 },
1697 .{
1698 .llvm_name = "knm",
1699 .extra_deps = &.{
1700 "avx512er",
1701 "avx512pf",
1702 "prefetchwt1",
1703 },
1704 },
1705 .{
1706 .llvm_name = "lakemont",
1707 .extra_deps = &.{"soft_float"},
1708 },
1709 .{
1710 .llvm_name = "meteorlake",
1711 .extra_deps = &.{ "smap", "smep" },
1712 },
1713 .{
1714 .llvm_name = "opteron",
1715 .extra_deps = &.{"3dnowa"},
1716 },
1717 .{
1718 .llvm_name = "opteron-sse3",
1719 .extra_deps = &.{"3dnowa"},
1720 },
1721 .{
1722 .llvm_name = "raptorlake",
1723 .extra_deps = &.{ "smap", "smep" },
1724 },
1725 .{
1726 .llvm_name = "rocketlake",
1727 .extra_deps = &.{ "smap", "smep" },
1728 },
1729 .{
1730 .llvm_name = "sapphirerapids",
1731 .extra_deps = &.{ "smap", "smep" },
1732 },
1733 .{
1734 .llvm_name = "silvermont",
1735 .extra_deps = &.{"smep"},
1736 },
1737 .{
1738 .llvm_name = "skx",
1739 .extra_deps = &.{ "smap", "smep" },
1740 },
1741 .{
1742 .llvm_name = "skylake",
1743 .extra_deps = &.{ "smap", "smep" },
1744 },
1745 .{
1746 .llvm_name = "skylake_avx512",
1747 .extra_deps = &.{ "smap", "smep" },
1748 },
1749 .{
1750 .llvm_name = "tigerlake",
1751 .extra_deps = &.{ "smap", "smep" },
1752 },
1753 .{
1754 .llvm_name = "winchip2",
1755 .extra_deps = &.{"3dnow"},
1756 },
1757 .{
1758 .llvm_name = "sse4.2",
1759 .extra_deps = &.{"crc32"},
1760 },
1761 .{
1762 .llvm_name = "znver1",
1763 .extra_deps = &.{ "smap", "smep" },
1764 },
1765 .{
1766 .llvm_name = "znver2",
1767 .extra_deps = &.{ "smap", "smep" },
1768 },
1769 .{
1770 .llvm_name = "znver3",
1771 .extra_deps = &.{ "smap", "smep" },
1772 },
1773 .{
1774 .llvm_name = "znver4",
1775 .extra_deps = &.{ "smap", "smep" },
1776 },
1777 .{
1778 .llvm_name = "znver5",
1779 .extra_deps = &.{ "smap", "smep" },
1780 },
1781 },
1782 .extra_features = &.{
1783 // Features removed from LLVM
1784 .{
1785 .zig_name = "3dnow",
1786 .desc = "Enable 3DNow! instructions",
1787 .deps = &.{"mmx"},
1788 },
1789 .{
1790 .zig_name = "3dnowa",
1791 .desc = "Enable 3DNow! Athlon instructions",
1792 .deps = &.{"3dnow"},
1793 },
1794 .{
1795 .zig_name = "avx512er",
1796 .desc = "Enable AVX-512 Exponential and Reciprocal Instructions",
1797 .deps = &.{"avx512f"},
1798 },
1799 .{
1800 .zig_name = "avx512pf",
1801 .desc = "Enable AVX-512 PreFetch Instructions",
1802 .deps = &.{"avx512f"},
1803 },
1804 .{
1805 .zig_name = "prefetchwt1",
1806 .desc = "Prefetch with Intent to Write and T1 Hint",
1807 .deps = &.{},
1808 },
1809 // Custom Zig features
1810 .{
1811 .zig_name = "bsf_bsr_0_clobbers_result",
1812 .desc = "BSF/BSR may clobber the lower 32-bits of the result register when the source is zero",
1813 .deps = &.{},
1814 },
1815 .{
1816 .zig_name = "smap",
1817 .desc = "Enable Supervisor Mode Access Prevention",
1818 .deps = &.{},
1819 },
1820 .{
1821 .zig_name = "smep",
1822 .desc = "Enable Supervisor Mode Execution Prevention",
1823 .deps = &.{},
1824 },
1825 },
1826 .extra_cpus = &.{
1827 .{
1828 .llvm_name = null,
1829 .zig_name = "i86",
1830 .features = &.{"16bit_mode"},
1831 },
1832 },
1833 .omit_cpus = &.{
1834 // LLVM defines a bunch of dumb aliases with foreach loops in X86.td.
1835 "pentium_mmx",
1836 "pentium_pro",
1837 "pentium_ii",
1838 "pentium_3m",
1839 "pentium_iii_no_xmm_regs",
1840 "pentium_iii",
1841 "pentium_m",
1842 "pentium4m",
1843 "pentium_4",
1844 "pentium_4_sse3",
1845 "core_2_duo_ssse3",
1846 "core_2_duo_sse4_1",
1847 "atom_sse4_2",
1848 "goldmont_plus",
1849 "core_i7_sse4_2",
1850 "core_aes_pclmulqdq",
1851 "corei7-avx",
1852 "core_2nd_gen_avx",
1853 "core-avx-i",
1854 "core_3rd_gen_avx",
1855 "core-avx2",
1856 "core_4th_gen_avx",
1857 "core_4th_gen_avx_tsx",
1858 "core_5th_gen_avx",
1859 "core_5th_gen_avx_tsx",
1860 "mic_avx512",
1861 "skylake_avx512",
1862 "icelake_client",
1863 "icelake_server",
1864 "graniterapids_d",
1865 "arrowlake_s",
1866 },
1867 },
1868 .{
1869 .zig_name = "xcore",
1870 .llvm = .{
1871 .name = "XCore",
1872 .td_name = "XCore",
1873 },
1874 },
1875 .{
1876 .zig_name = "xtensa",
1877 .llvm = .{
1878 .name = "Xtensa",
1879 .td_name = "Xtensa",
1880 },
1881 },
1882};
1883
1884pub fn main() anyerror!void {
1885 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
1886 defer arena_state.deinit();
1887 const arena = arena_state.allocator();
1888
1889 var args = try std.process.argsWithAllocator(arena);
1890 const args0 = args.next().?;
1891
1892 const llvm_tblgen_exe = args.next() orelse
1893 usageAndExit(args0, 1);
1894
1895 if (std.mem.eql(u8, llvm_tblgen_exe, "--help")) {
1896 usageAndExit(args0, 0);
1897 }
1898 if (std.mem.startsWith(u8, llvm_tblgen_exe, "-")) {
1899 usageAndExit(args0, 1);
1900 }
1901
1902 const llvm_src_root = args.next() orelse
1903 usageAndExit(args0, 1);
1904
1905 if (std.mem.startsWith(u8, llvm_src_root, "-")) {
1906 usageAndExit(args0, 1);
1907 }
1908
1909 const zig_src_root = args.next() orelse
1910 usageAndExit(args0, 1);
1911
1912 if (std.mem.startsWith(u8, zig_src_root, "-")) {
1913 usageAndExit(args0, 1);
1914 }
1915
1916 var filter: ?[]const u8 = null;
1917 if (args.next()) |arg| filter = arg;
1918
1919 // there shouldn't be any more argument after the optional filter
1920 if (args.skip()) usageAndExit(args0, 1);
1921
1922 var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});
1923 defer zig_src_dir.close();
1924
1925 const root_progress = std.Progress.start(.{ .estimated_total_items = targets.len });
1926 defer root_progress.end();
1927
1928 if (builtin.single_threaded) {
1929 for (targets) |target| {
1930 if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
1931 try processOneTarget(.{
1932 .llvm_tblgen_exe = llvm_tblgen_exe,
1933 .llvm_src_root = llvm_src_root,
1934 .zig_src_dir = zig_src_dir,
1935 .root_progress = root_progress,
1936 .target = target,
1937 });
1938 }
1939 } else {
1940 var pool: std.Thread.Pool = undefined;
1941 try pool.init(.{ .allocator = arena, .n_jobs = targets.len });
1942 defer pool.deinit();
1943
1944 for (targets) |target| {
1945 if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
1946 const job = Job{
1947 .llvm_tblgen_exe = llvm_tblgen_exe,
1948 .llvm_src_root = llvm_src_root,
1949 .zig_src_dir = zig_src_dir,
1950 .root_progress = root_progress,
1951 .target = target,
1952 };
1953 try pool.spawn(processOneTarget, .{job});
1954 }
1955 }
1956}
1957
1958const Job = struct {
1959 llvm_tblgen_exe: []const u8,
1960 llvm_src_root: []const u8,
1961 zig_src_dir: std.fs.Dir,
1962 root_progress: std.Progress.Node,
1963 target: ArchTarget,
1964};
1965
1966fn processOneTarget(job: Job) void {
1967 errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)});
1968 const target = job.target;
1969
1970 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
1971 defer arena_state.deinit();
1972 const arena = arena_state.allocator();
1973
1974 const progress_node = job.root_progress.start(target.zig_name, 3);
1975 defer progress_node.end();
1976
1977 var features_table = std.StringHashMap(Feature).init(arena);
1978 var all_features = std.array_list.Managed(Feature).init(arena);
1979 var all_cpus = std.array_list.Managed(Cpu).init(arena);
1980
1981 if (target.llvm) |llvm| {
1982 const tblgen_progress = progress_node.start("running llvm-tblgen", 0);
1983
1984 const child_args = [_][]const u8{
1985 job.llvm_tblgen_exe,
1986 "--dump-json",
1987 try std.fmt.allocPrint(arena, "{s}/llvm/lib/Target/{s}/{s}.td", .{
1988 job.llvm_src_root,
1989 llvm.name,
1990 llvm.td_name,
1991 }),
1992 try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{job.llvm_src_root}),
1993 try std.fmt.allocPrint(arena, "-I={s}/llvm/lib/Target/{s}", .{
1994 job.llvm_src_root, llvm.name,
1995 }),
1996 };
1997
1998 const child_result = try std.process.Child.run(.{
1999 .allocator = arena,
2000 .argv = &child_args,
2001 .max_output_bytes = 500 * 1024 * 1024,
2002 });
2003 tblgen_progress.end();
2004 if (child_result.stderr.len != 0) {
2005 std.debug.print("{s}\n", .{child_result.stderr});
2006 }
2007
2008 const json_text = switch (child_result.term) {
2009 .Exited => |code| if (code == 0) child_result.stdout else {
2010 std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
2011 std.process.exit(1);
2012 },
2013 else => {
2014 std.debug.print("llvm-tblgen crashed\n", .{});
2015 std.process.exit(1);
2016 },
2017 };
2018
2019 const json_parse_progress = progress_node.start("parsing JSON", 0);
2020
2021 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
2022 defer parsed.deinit();
2023 const root_map = &parsed.value.object;
2024 json_parse_progress.end();
2025
2026 const collate_progress = progress_node.start("collating LLVM data", 0);
2027
2028 // So far, LLVM only has a few aliases for the same CPU.
2029 const Alias = struct {
2030 llvm: []const u8,
2031 zig: []const u8,
2032 };
2033 var cpu_aliases = std.StringHashMap(std.ArrayList(*Alias)).init(arena);
2034
2035 {
2036 var it = root_map.iterator();
2037 while (it.next()) |kv| {
2038 if (kv.key_ptr.len == 0) continue;
2039 if (kv.key_ptr.*[0] == '!') continue;
2040 if (kv.value_ptr.* != .object) continue;
2041 if (hasSuperclass(&kv.value_ptr.object, "ProcessorAlias")) {
2042 // Note that `Name` is actually the alias, while `Alias` is the name that will have
2043 // a full `Processor` object defined.
2044 const llvm_alias = kv.value_ptr.object.get("Name").?.string;
2045 const llvm_name = kv.value_ptr.object.get("Alias").?.string;
2046
2047 const gop = try cpu_aliases.getOrPut(try llvmNameToZigName(arena, llvm_name));
2048
2049 if (!gop.found_existing) {
2050 gop.value_ptr.* = .empty;
2051 }
2052
2053 const alias = try arena.create(Alias);
2054 alias.* = .{
2055 .llvm = llvm_alias,
2056 .zig = try llvmNameToZigName(arena, llvm_alias),
2057 };
2058 try gop.value_ptr.append(arena, alias);
2059 }
2060 }
2061 }
2062
2063 {
2064 var it = root_map.iterator();
2065 while (it.next()) |kv| {
2066 if (kv.key_ptr.len == 0) continue;
2067 if (kv.key_ptr.*[0] == '!') continue;
2068 if (kv.value_ptr.* != .object) continue;
2069 if (hasSuperclass(&kv.value_ptr.object, "SubtargetFeature")) {
2070 const llvm_name = kv.value_ptr.object.get("Name").?.string;
2071 if (llvm_name.len == 0) continue;
2072
2073 var zig_name = try llvmNameToZigName(arena, llvm_name);
2074 var desc = kv.value_ptr.object.get("Desc").?.string;
2075 var deps = std.array_list.Managed([]const u8).init(arena);
2076 var omit = false;
2077 var flatten = false;
2078 var omit_deps: []const []const u8 = &.{};
2079 var extra_deps: []const []const u8 = &.{};
2080 for (target.feature_overrides) |feature_override| {
2081 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
2082 if (feature_override.omit) {
2083 // Still put the feature into the table so that we can
2084 // expand dependencies for the feature overrides marked `flatten`.
2085 omit = true;
2086 }
2087 if (feature_override.flatten) {
2088 flatten = true;
2089 }
2090 if (feature_override.zig_name) |override_name| {
2091 zig_name = override_name;
2092 }
2093 if (feature_override.desc) |override_desc| {
2094 desc = override_desc;
2095 }
2096 omit_deps = feature_override.omit_deps;
2097 extra_deps = feature_override.extra_deps;
2098 break;
2099 }
2100 }
2101 const implies = kv.value_ptr.object.get("Implies").?.array;
2102 for (implies.items) |imply| {
2103 const other_key = imply.object.get("def").?.string;
2104 const other_obj = root_map.get(other_key).?.object;
2105 const other_llvm_name = other_obj.get("Name").?.string;
2106 const other_zig_name = (try llvmFeatureNameToZigNameOmit(
2107 arena,
2108 target,
2109 other_llvm_name,
2110 )) orelse continue;
2111 for (omit_deps) |omit_dep| {
2112 if (mem.eql(u8, other_zig_name, omit_dep)) break;
2113 } else {
2114 try deps.append(other_zig_name);
2115 }
2116 }
2117 // This is used by AArch64.
2118 if (kv.value_ptr.object.get("DefaultExts")) |exts_val| {
2119 for (exts_val.array.items) |ext| {
2120 const other_key = ext.object.get("def").?.string;
2121 const other_obj = root_map.get(other_key).?.object;
2122 const other_llvm_name = other_obj.get("Name").?.string;
2123 const other_zig_name = (try llvmFeatureNameToZigNameOmit(
2124 arena,
2125 target,
2126 other_llvm_name,
2127 )) orelse continue;
2128 for (omit_deps) |omit_dep| {
2129 if (mem.eql(u8, other_zig_name, omit_dep)) break;
2130 } else {
2131 try deps.append(other_zig_name);
2132 }
2133 }
2134 }
2135 for (extra_deps) |extra_dep| {
2136 try deps.append(extra_dep);
2137 }
2138 const feature: Feature = .{
2139 .llvm_name = llvm_name,
2140 .zig_name = zig_name,
2141 .desc = desc,
2142 .deps = deps.items,
2143 .flatten = flatten,
2144 };
2145 try features_table.put(zig_name, feature);
2146 if (!omit and !flatten) {
2147 try all_features.append(feature);
2148 }
2149 }
2150 if (hasSuperclass(&kv.value_ptr.object, "Processor")) {
2151 const llvm_name = kv.value_ptr.object.get("Name").?.string;
2152 if (llvm_name.len == 0) continue;
2153 const omitted = for (target.omit_cpus) |omit_cpu_name| {
2154 if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;
2155 } else false;
2156 if (omitted) continue;
2157
2158 var zig_name = try llvmNameToZigName(arena, llvm_name);
2159 var deps = std.array_list.Managed([]const u8).init(arena);
2160 var omit_deps: []const []const u8 = &.{};
2161 var extra_deps: []const []const u8 = &.{};
2162 for (target.feature_overrides) |feature_override| {
2163 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
2164 if (feature_override.omit) {
2165 continue;
2166 }
2167 if (feature_override.zig_name) |override_name| {
2168 zig_name = override_name;
2169 }
2170 omit_deps = feature_override.omit_deps;
2171 extra_deps = feature_override.extra_deps;
2172 break;
2173 }
2174 }
2175 const features = kv.value_ptr.object.get("Features").?.array;
2176 for (features.items) |feature| {
2177 const feature_key = feature.object.get("def").?.string;
2178 const feature_obj = root_map.get(feature_key).?.object;
2179 const feature_llvm_name = feature_obj.get("Name").?.string;
2180 if (feature_llvm_name.len == 0) continue;
2181 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
2182 arena,
2183 target,
2184 feature_llvm_name,
2185 )) orelse continue;
2186 for (omit_deps) |omit_dep| {
2187 if (mem.eql(u8, feature_zig_name, omit_dep)) break;
2188 } else {
2189 try deps.append(feature_zig_name);
2190 }
2191 }
2192 for (extra_deps) |extra_dep| {
2193 try deps.append(extra_dep);
2194 }
2195 const tune_features = kv.value_ptr.object.get("TuneFeatures").?.array;
2196 for (tune_features.items) |feature| {
2197 const feature_key = feature.object.get("def").?.string;
2198 const feature_obj = root_map.get(feature_key).?.object;
2199 const feature_llvm_name = feature_obj.get("Name").?.string;
2200 if (feature_llvm_name.len == 0) continue;
2201 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
2202 arena,
2203 target,
2204 feature_llvm_name,
2205 )) orelse continue;
2206 try deps.append(feature_zig_name);
2207 }
2208 try all_cpus.append(.{
2209 .llvm_name = llvm_name,
2210 .zig_name = zig_name,
2211 .features = deps.items,
2212 });
2213
2214 if (cpu_aliases.get(zig_name)) |aliases| {
2215 alias_it: for (aliases.items) |alias| {
2216 for (target.omit_cpus) |omit_cpu_name| {
2217 if (mem.eql(u8, omit_cpu_name, alias.llvm)) continue :alias_it;
2218 }
2219
2220 try all_cpus.append(.{
2221 .llvm_name = alias.llvm,
2222 .zig_name = alias.zig,
2223 .features = deps.items,
2224 });
2225 }
2226 }
2227 }
2228 }
2229 }
2230
2231 collate_progress.end();
2232 }
2233
2234 for (target.extra_features) |extra_feature| {
2235 try features_table.put(extra_feature.zig_name, extra_feature);
2236 try all_features.append(extra_feature);
2237 }
2238 for (target.extra_cpus) |extra_cpu| {
2239 try all_cpus.append(extra_cpu);
2240 }
2241 mem.sort(Feature, all_features.items, {}, featureLessThan);
2242 mem.sort(Cpu, all_cpus.items, {}, cpuLessThan);
2243
2244 const render_progress = progress_node.start("rendering Zig code", 0);
2245
2246 var target_dir = try job.zig_src_dir.openDir("lib/std/Target", .{});
2247 defer target_dir.close();
2248
2249 const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{target.zig_name});
2250 var zig_code_file = try target_dir.createFile(zig_code_basename, .{});
2251 defer zig_code_file.close();
2252
2253 var zig_code_file_buffer: [4096]u8 = undefined;
2254 var zig_code_file_writer = zig_code_file.writer(&zig_code_file_buffer);
2255 const w = &zig_code_file_writer.interface;
2256
2257 try w.writeAll(
2258 \\//! This file is auto-generated by tools/update_cpu_features.zig.
2259 \\
2260 \\const std = @import("../std.zig");
2261 \\const CpuFeature = std.Target.Cpu.Feature;
2262 \\const CpuModel = std.Target.Cpu.Model;
2263 \\
2264 \\pub const Feature = enum {
2265 );
2266
2267 for (all_features.items, 0..) |feature, i| {
2268 try w.print("\n {f},", .{std.zig.fmtIdPU(feature.zig_name)});
2269
2270 if (i == all_features.items.len - 1) try w.writeAll("\n");
2271 }
2272
2273 try w.writeAll(
2274 \\};
2275 \\
2276 \\pub const featureSet = CpuFeature.FeatureSetFns(Feature).featureSet;
2277 \\pub const featureSetHas = CpuFeature.FeatureSetFns(Feature).featureSetHas;
2278 \\pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny;
2279 \\pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll;
2280 \\
2281 \\pub const all_features = blk: {
2282 \\
2283 );
2284 if (target.branch_quota) |branch_quota| {
2285 try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota});
2286 }
2287 try w.writeAll(
2288 \\ const len = @typeInfo(Feature).@"enum".fields.len;
2289 \\ std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
2290 \\ var result: [len]CpuFeature = undefined;
2291 \\
2292 );
2293
2294 for (all_features.items) |feature| {
2295 if (feature.llvm_name) |llvm_name| {
2296 try w.print(
2297 \\ result[@intFromEnum(Feature.{f})] = .{{
2298 \\ .llvm_name = "{f}",
2299 \\ .description = "{f}",
2300 \\ .dependencies = featureSet(&[_]Feature{{
2301 ,
2302 .{
2303 std.zig.fmtIdPU(feature.zig_name),
2304 std.zig.fmtString(llvm_name),
2305 std.zig.fmtString(feature.desc),
2306 },
2307 );
2308 } else {
2309 try w.print(
2310 \\ result[@intFromEnum(Feature.{f})] = .{{
2311 \\ .llvm_name = null,
2312 \\ .description = "{f}",
2313 \\ .dependencies = featureSet(&[_]Feature{{
2314 ,
2315 .{
2316 std.zig.fmtIdPU(feature.zig_name),
2317 std.zig.fmtString(feature.desc),
2318 },
2319 );
2320 }
2321 var deps_set = std.StringHashMap(void).init(arena);
2322 for (feature.deps) |dep| {
2323 try putDep(&deps_set, features_table, dep);
2324 }
2325 try pruneFeatures(arena, features_table, &deps_set);
2326 var dependencies = std.array_list.Managed([]const u8).init(arena);
2327 {
2328 var it = deps_set.keyIterator();
2329 while (it.next()) |key| {
2330 try dependencies.append(key.*);
2331 }
2332 }
2333 mem.sort([]const u8, dependencies.items, {}, asciiLessThan);
2334
2335 if (dependencies.items.len == 0) {
2336 try w.writeAll(
2337 \\}),
2338 \\ };
2339 \\
2340 );
2341 } else {
2342 try w.writeAll("\n");
2343 for (dependencies.items) |dep| {
2344 try w.print(" .{f},\n", .{std.zig.fmtIdPU(dep)});
2345 }
2346 try w.writeAll(
2347 \\ }),
2348 \\ };
2349 \\
2350 );
2351 }
2352 }
2353 try w.writeAll(
2354 \\ const ti = @typeInfo(Feature);
2355 \\ for (&result, 0..) |*elem, i| {
2356 \\ elem.index = i;
2357 \\ elem.name = ti.@"enum".fields[i].name;
2358 \\ }
2359 \\ break :blk result;
2360 \\};
2361 \\
2362 \\pub const cpu = struct {
2363 \\
2364 );
2365 for (all_cpus.items) |cpu| {
2366 var deps_set = std.StringHashMap(void).init(arena);
2367 for (cpu.features) |feature_zig_name| {
2368 try putDep(&deps_set, features_table, feature_zig_name);
2369 }
2370 try pruneFeatures(arena, features_table, &deps_set);
2371 var cpu_features = std.array_list.Managed([]const u8).init(arena);
2372 {
2373 var it = deps_set.keyIterator();
2374 while (it.next()) |key| {
2375 try cpu_features.append(key.*);
2376 }
2377 }
2378 mem.sort([]const u8, cpu_features.items, {}, asciiLessThan);
2379 if (cpu.llvm_name) |llvm_name| {
2380 try w.print(
2381 \\ pub const {f}: CpuModel = .{{
2382 \\ .name = "{f}",
2383 \\ .llvm_name = "{f}",
2384 \\ .features = featureSet(&[_]Feature{{
2385 , .{
2386 std.zig.fmtId(cpu.zig_name),
2387 std.zig.fmtString(cpu.zig_name),
2388 std.zig.fmtString(llvm_name),
2389 });
2390 } else {
2391 try w.print(
2392 \\ pub const {f}: CpuModel = .{{
2393 \\ .name = "{f}",
2394 \\ .llvm_name = null,
2395 \\ .features = featureSet(&[_]Feature{{
2396 , .{
2397 std.zig.fmtId(cpu.zig_name),
2398 std.zig.fmtString(cpu.zig_name),
2399 });
2400 }
2401 if (cpu_features.items.len == 0) {
2402 try w.writeAll(
2403 \\}),
2404 \\ };
2405 \\
2406 );
2407 } else {
2408 try w.writeAll("\n");
2409 for (cpu_features.items) |feature_zig_name| {
2410 try w.print(" .{f},\n", .{std.zig.fmtIdPU(feature_zig_name)});
2411 }
2412 try w.writeAll(
2413 \\ }),
2414 \\ };
2415 \\
2416 );
2417 }
2418 }
2419
2420 try w.writeAll(
2421 \\};
2422 \\
2423 );
2424 try w.flush();
2425
2426 render_progress.end();
2427}
2428
2429fn usageAndExit(arg0: []const u8, code: u8) noreturn {
2430 const stderr, _ = std.debug.lockStderrWriter(&.{});
2431 stderr.print(
2432 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]
2433 \\
2434 \\Updates lib/std/target/<target>.zig from llvm/lib/Target/<Target>/<Target>.td .
2435 \\
2436 \\On a less beefy system, or when debugging, compile with -fsingle-threaded.
2437 \\
2438 , .{arg0}) catch std.process.exit(1);
2439 std.process.exit(code);
2440}
2441
2442fn featureLessThan(_: void, a: Feature, b: Feature) bool {
2443 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name);
2444}
2445
2446fn cpuLessThan(_: void, a: Cpu, b: Cpu) bool {
2447 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name);
2448}
2449
2450fn asciiLessThan(_: void, a: []const u8, b: []const u8) bool {
2451 return std.ascii.lessThanIgnoreCase(a, b);
2452}
2453
2454fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 {
2455 const duped = try arena.dupe(u8, llvm_name);
2456 for (duped) |*byte| switch (byte.*) {
2457 '-', '.' => byte.* = '_',
2458 else => continue,
2459 };
2460 return duped;
2461}
2462
2463fn llvmFeatureNameToZigNameOmit(
2464 arena: mem.Allocator,
2465 target: ArchTarget,
2466 llvm_name: []const u8,
2467) !?[]const u8 {
2468 for (target.feature_overrides) |feature_override| {
2469 if (mem.eql(u8, feature_override.llvm_name, llvm_name)) {
2470 if (feature_override.omit) return null;
2471 return feature_override.zig_name orelse break;
2472 }
2473 }
2474 return try llvmNameToZigName(arena, llvm_name);
2475}
2476
2477fn hasSuperclass(obj: *const json.ObjectMap, class_name: []const u8) bool {
2478 const superclasses_json = obj.get("!superclasses") orelse return false;
2479 for (superclasses_json.array.items) |superclass_json| {
2480 const superclass = superclass_json.string;
2481 if (std.mem.eql(u8, superclass, class_name)) {
2482 return true;
2483 }
2484 }
2485 return false;
2486}
2487
2488fn pruneFeatures(
2489 arena: mem.Allocator,
2490 features_table: std.StringHashMap(Feature),
2491 deps_set: *std.StringHashMap(void),
2492) !void {
2493 // For each element, recursively iterate over the dependencies and add
2494 // everything we find to a "deletion set".
2495 // Then, iterate over the deletion set and delete all that stuff from `deps_set`.
2496 var deletion_set = std.StringHashMap(void).init(arena);
2497 {
2498 var it = deps_set.keyIterator();
2499 while (it.next()) |key| {
2500 const feature = features_table.get(key.*).?;
2501 try walkFeatures(features_table, &deletion_set, feature);
2502 }
2503 }
2504 {
2505 var it = deletion_set.keyIterator();
2506 while (it.next()) |key| {
2507 _ = deps_set.remove(key.*);
2508 }
2509 }
2510}
2511
2512fn walkFeatures(
2513 features_table: std.StringHashMap(Feature),
2514 deletion_set: *std.StringHashMap(void),
2515 feature: Feature,
2516) error{OutOfMemory}!void {
2517 for (feature.deps) |dep| {
2518 try deletion_set.put(dep, {});
2519 const other_feature = features_table.get(dep).?;
2520 try walkFeatures(features_table, deletion_set, other_feature);
2521 }
2522}
2523
2524fn putDep(
2525 deps_set: *std.StringHashMap(void),
2526 features_table: std.StringHashMap(Feature),
2527 zig_feature_name: []const u8,
2528) error{OutOfMemory}!void {
2529 const feature = features_table.get(zig_feature_name).?;
2530 if (feature.flatten) {
2531 for (feature.deps) |dep| {
2532 try putDep(deps_set, features_table, dep);
2533 }
2534 } else {
2535 try deps_set.put(zig_feature_name, {});
2536 }
2537}