authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-27 15:57:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-27 15:57:01-07:00
loge02acc028825ec83951946e4947883c2c96211ce
tree9318e3538cb165e831d2a8518ffadab0eb7656ff
parent9082d761684b0717c45db93964bb7e569702af99

tools/update_cpu_features: better patching API

With this change, added & modified cpus & features participate in the same pruning system, and sorting takes into account the zig name, not the pre-modified llvm name. The modified target files in this commit are due to the improved sorting and pruning. The script now fully supports extra cpus & features.

5 files changed, 355 insertions(+), 288 deletions(-)

lib/std/target/amdgpu.zig+6-6
......@@ -41,8 +41,8 @@ pub const Feature = enum {
4141 get_wave_id_inst,
4242 gfx10,
4343 gfx10_3_insts,
44 gfx10_insts,
4544 gfx10_b_encoding,
45 gfx10_insts,
4646 gfx7_gfx8_gfx9_insts,
4747 gfx8_insts,
4848 gfx9,
......@@ -347,16 +347,16 @@ pub const all_features = blk: {
347347 .description = "Additional instructions for GFX10.3",
348348 .dependencies = featureSet(&[_]Feature{}),
349349 };
350 result[@enumToInt(Feature.gfx10_insts)] = .{
351 .llvm_name = "gfx10-insts",
352 .description = "Additional instructions for GFX10+",
353 .dependencies = featureSet(&[_]Feature{}),
354 };
355350 result[@enumToInt(Feature.gfx10_b_encoding)] = .{
356351 .llvm_name = "gfx10_b-encoding",
357352 .description = "Encoding format GFX10_B",
358353 .dependencies = featureSet(&[_]Feature{}),
359354 };
355 result[@enumToInt(Feature.gfx10_insts)] = .{
356 .llvm_name = "gfx10-insts",
357 .description = "Additional instructions for GFX10+",
358 .dependencies = featureSet(&[_]Feature{}),
359 };
360360 result[@enumToInt(Feature.gfx7_gfx8_gfx9_insts)] = .{
361361 .llvm_name = "gfx7-gfx8-gfx9-insts",
362362 .description = "Instructions shared in GFX7, GFX8, GFX9",
lib/std/target/powerpc.zig+12-12
......@@ -56,10 +56,10 @@ pub const Feature = enum {
5656 power8_vector,
5757 power9_altivec,
5858 power9_vector,
59 ppc_postra_sched,
60 ppc_prera_sched,
6159 ppc4xx,
6260 ppc6xx,
61 ppc_postra_sched,
62 ppc_prera_sched,
6363 predictable_select_expensive,
6464 prefix_instrs,
6565 recipprec,
......@@ -397,16 +397,6 @@ pub const all_features = blk: {
397397 .power9_altivec,
398398 }),
399399 };
400 result[@enumToInt(Feature.ppc_postra_sched)] = .{
401 .llvm_name = "ppc-postra-sched",
402 .description = "Use PowerPC post-RA scheduling strategy",
403 .dependencies = featureSet(&[_]Feature{}),
404 };
405 result[@enumToInt(Feature.ppc_prera_sched)] = .{
406 .llvm_name = "ppc-prera-sched",
407 .description = "Use PowerPC pre-RA scheduling strategy",
408 .dependencies = featureSet(&[_]Feature{}),
409 };
410400 result[@enumToInt(Feature.ppc4xx)] = .{
411401 .llvm_name = "ppc4xx",
412402 .description = "Enable PPC 4xx instructions",
......@@ -417,6 +407,16 @@ pub const all_features = blk: {
417407 .description = "Enable PPC 6xx instructions",
418408 .dependencies = featureSet(&[_]Feature{}),
419409 };
410 result[@enumToInt(Feature.ppc_postra_sched)] = .{
411 .llvm_name = "ppc-postra-sched",
412 .description = "Use PowerPC post-RA scheduling strategy",
413 .dependencies = featureSet(&[_]Feature{}),
414 };
415 result[@enumToInt(Feature.ppc_prera_sched)] = .{
416 .llvm_name = "ppc-prera-sched",
417 .description = "Use PowerPC pre-RA scheduling strategy",
418 .dependencies = featureSet(&[_]Feature{}),
419 };
420420 result[@enumToInt(Feature.predictable_select_expensive)] = .{
421421 .llvm_name = "predictable-select-expensive",
422422 .description = "Prefer likely predicted branches over selects",
lib/std/target/riscv.zig-2
......@@ -390,7 +390,6 @@ pub const cpu = struct {
390390 .a,
391391 .c,
392392 .d,
393 .f,
394393 .m,
395394 }),
396395 };
......@@ -402,7 +401,6 @@ pub const cpu = struct {
402401 .a,
403402 .c,
404403 .d,
405 .f,
406404 .m,
407405 }),
408406 };
lib/std/target/x86.zig+132-132
......@@ -121,12 +121,12 @@ pub const Feature = enum {
121121 slow_unaligned_mem_32,
122122 soft_float,
123123 sse,
124 sse_unaligned_mem,
125124 sse2,
126125 sse3,
127126 sse4_1,
128127 sse4_2,
129128 sse4a,
129 sse_unaligned_mem,
130130 ssse3,
131131 tbm,
132132 tsxldtrk,
......@@ -805,11 +805,6 @@ pub const all_features = blk: {
805805 .description = "Enable SSE instructions",
806806 .dependencies = featureSet(&[_]Feature{}),
807807 };
808 result[@enumToInt(Feature.sse_unaligned_mem)] = .{
809 .llvm_name = "sse-unaligned-mem",
810 .description = "Allow unaligned memory operands with SSE instructions",
811 .dependencies = featureSet(&[_]Feature{}),
812 };
813808 result[@enumToInt(Feature.sse2)] = .{
814809 .llvm_name = "sse2",
815810 .description = "Enable SSE2 instructions",
......@@ -845,6 +840,11 @@ pub const all_features = blk: {
845840 .sse3,
846841 }),
847842 };
843 result[@enumToInt(Feature.sse_unaligned_mem)] = .{
844 .llvm_name = "sse-unaligned-mem",
845 .description = "Allow unaligned memory operands with SSE instructions",
846 .dependencies = featureSet(&[_]Feature{}),
847 };
848848 result[@enumToInt(Feature.ssse3)] = .{
849849 .llvm_name = "ssse3",
850850 .description = "Enable SSSE3 instructions",
......@@ -962,6 +962,45 @@ pub const all_features = blk: {
962962};
963963
964964pub const cpu = struct {
965 pub const _i386 = CpuModel{
966 .name = "_i386",
967 .llvm_name = "i386",
968 .features = featureSet(&[_]Feature{
969 .slow_unaligned_mem_16,
970 .vzeroupper,
971 .x87,
972 }),
973 };
974 pub const _i486 = CpuModel{
975 .name = "_i486",
976 .llvm_name = "i486",
977 .features = featureSet(&[_]Feature{
978 .slow_unaligned_mem_16,
979 .vzeroupper,
980 .x87,
981 }),
982 };
983 pub const _i586 = CpuModel{
984 .name = "_i586",
985 .llvm_name = "i586",
986 .features = featureSet(&[_]Feature{
987 .cx8,
988 .slow_unaligned_mem_16,
989 .vzeroupper,
990 .x87,
991 }),
992 };
993 pub const _i686 = CpuModel{
994 .name = "_i686",
995 .llvm_name = "i686",
996 .features = featureSet(&[_]Feature{
997 .cmov,
998 .cx8,
999 .slow_unaligned_mem_16,
1000 .vzeroupper,
1001 .x87,
1002 }),
1003 };
9651004 pub const alderlake = CpuModel{
9661005 .name = "alderlake",
9671006 .llvm_name = "alderlake",
......@@ -1049,43 +1088,45 @@ pub const cpu = struct {
10491088 .x87,
10501089 }),
10511090 };
1052 pub const athlon_4 = CpuModel{
1053 .name = "athlon_4",
1054 .llvm_name = "athlon-4",
1091 pub const athlon64 = CpuModel{
1092 .name = "athlon64",
1093 .llvm_name = "athlon64",
10551094 .features = featureSet(&[_]Feature{
10561095 .@"3dnowa",
1096 .@"64bit",
10571097 .cmov,
10581098 .cx8,
1099 .fast_scalar_shift_masks,
10591100 .fxsr,
10601101 .nopl,
10611102 .slow_shld,
10621103 .slow_unaligned_mem_16,
1063 .sse,
1104 .sse2,
10641105 .vzeroupper,
10651106 .x87,
10661107 }),
10671108 };
1068 pub const athlon_fx = CpuModel{
1069 .name = "athlon_fx",
1070 .llvm_name = "athlon-fx",
1109 pub const athlon64_sse3 = CpuModel{
1110 .name = "athlon64_sse3",
1111 .llvm_name = "athlon64-sse3",
10711112 .features = featureSet(&[_]Feature{
10721113 .@"3dnowa",
10731114 .@"64bit",
10741115 .cmov,
1075 .cx8,
1116 .cx16,
10761117 .fast_scalar_shift_masks,
10771118 .fxsr,
10781119 .nopl,
10791120 .slow_shld,
10801121 .slow_unaligned_mem_16,
1081 .sse2,
1122 .sse3,
10821123 .vzeroupper,
10831124 .x87,
10841125 }),
10851126 };
1086 pub const athlon_mp = CpuModel{
1087 .name = "athlon_mp",
1088 .llvm_name = "athlon-mp",
1127 pub const athlon_4 = CpuModel{
1128 .name = "athlon_4",
1129 .llvm_name = "athlon-4",
10891130 .features = featureSet(&[_]Feature{
10901131 .@"3dnowa",
10911132 .cmov,
......@@ -1099,23 +1140,27 @@ pub const cpu = struct {
10991140 .x87,
11001141 }),
11011142 };
1102 pub const athlon_tbird = CpuModel{
1103 .name = "athlon_tbird",
1104 .llvm_name = "athlon-tbird",
1143 pub const athlon_fx = CpuModel{
1144 .name = "athlon_fx",
1145 .llvm_name = "athlon-fx",
11051146 .features = featureSet(&[_]Feature{
11061147 .@"3dnowa",
1148 .@"64bit",
11071149 .cmov,
11081150 .cx8,
1151 .fast_scalar_shift_masks,
1152 .fxsr,
11091153 .nopl,
11101154 .slow_shld,
11111155 .slow_unaligned_mem_16,
1156 .sse2,
11121157 .vzeroupper,
11131158 .x87,
11141159 }),
11151160 };
1116 pub const athlon_xp = CpuModel{
1117 .name = "athlon_xp",
1118 .llvm_name = "athlon-xp",
1161 pub const athlon_mp = CpuModel{
1162 .name = "athlon_mp",
1163 .llvm_name = "athlon-mp",
11191164 .features = featureSet(&[_]Feature{
11201165 .@"3dnowa",
11211166 .cmov,
......@@ -1129,38 +1174,32 @@ pub const cpu = struct {
11291174 .x87,
11301175 }),
11311176 };
1132 pub const athlon64 = CpuModel{
1133 .name = "athlon64",
1134 .llvm_name = "athlon64",
1177 pub const athlon_tbird = CpuModel{
1178 .name = "athlon_tbird",
1179 .llvm_name = "athlon-tbird",
11351180 .features = featureSet(&[_]Feature{
11361181 .@"3dnowa",
1137 .@"64bit",
11381182 .cmov,
11391183 .cx8,
1140 .fast_scalar_shift_masks,
1141 .fxsr,
11421184 .nopl,
11431185 .slow_shld,
11441186 .slow_unaligned_mem_16,
1145 .sse2,
11461187 .vzeroupper,
11471188 .x87,
11481189 }),
11491190 };
1150 pub const athlon64_sse3 = CpuModel{
1151 .name = "athlon64_sse3",
1152 .llvm_name = "athlon64-sse3",
1191 pub const athlon_xp = CpuModel{
1192 .name = "athlon_xp",
1193 .llvm_name = "athlon-xp",
11531194 .features = featureSet(&[_]Feature{
11541195 .@"3dnowa",
1155 .@"64bit",
11561196 .cmov,
1157 .cx16,
1158 .fast_scalar_shift_masks,
1197 .cx8,
11591198 .fxsr,
11601199 .nopl,
11611200 .slow_shld,
11621201 .slow_unaligned_mem_16,
1163 .sse3,
1202 .sse,
11641203 .vzeroupper,
11651204 .x87,
11661205 }),
......@@ -1637,33 +1676,22 @@ pub const cpu = struct {
16371676 .xsaves,
16381677 }),
16391678 };
1640 pub const core_avx_i = CpuModel{
1641 .name = "core_avx_i",
1642 .llvm_name = "core-avx-i",
1679 pub const core2 = CpuModel{
1680 .name = "core2",
1681 .llvm_name = "core2",
16431682 .features = featureSet(&[_]Feature{
16441683 .@"64bit",
16451684 .cmov,
16461685 .cx16,
1647 .f16c,
1648 .false_deps_popcnt,
1649 .fast_15bytenop,
1650 .fast_scalar_fsqrt,
1651 .fast_shld_rotate,
1652 .fsgsbase,
16531686 .fxsr,
1654 .idivq_to_divl,
16551687 .macrofusion,
16561688 .mmx,
16571689 .nopl,
1658 .pclmul,
1659 .popcnt,
1660 .rdrnd,
16611690 .sahf,
1662 .slow_3ops_lea,
1663 .slow_unaligned_mem_32,
1691 .slow_unaligned_mem_16,
1692 .ssse3,
16641693 .vzeroupper,
16651694 .x87,
1666 .xsaveopt,
16671695 }),
16681696 };
16691697 pub const core_avx2 = CpuModel{
......@@ -1704,22 +1732,33 @@ pub const cpu = struct {
17041732 .xsaveopt,
17051733 }),
17061734 };
1707 pub const core2 = CpuModel{
1708 .name = "core2",
1709 .llvm_name = "core2",
1735 pub const core_avx_i = CpuModel{
1736 .name = "core_avx_i",
1737 .llvm_name = "core-avx-i",
17101738 .features = featureSet(&[_]Feature{
17111739 .@"64bit",
17121740 .cmov,
17131741 .cx16,
1742 .f16c,
1743 .false_deps_popcnt,
1744 .fast_15bytenop,
1745 .fast_scalar_fsqrt,
1746 .fast_shld_rotate,
1747 .fsgsbase,
17141748 .fxsr,
1749 .idivq_to_divl,
17151750 .macrofusion,
17161751 .mmx,
17171752 .nopl,
1753 .pclmul,
1754 .popcnt,
1755 .rdrnd,
17181756 .sahf,
1719 .slow_unaligned_mem_16,
1720 .ssse3,
1757 .slow_3ops_lea,
1758 .slow_unaligned_mem_32,
17211759 .vzeroupper,
17221760 .x87,
1761 .xsaveopt,
17231762 }),
17241763 };
17251764 pub const corei7 = CpuModel{
......@@ -1900,45 +1939,6 @@ pub const cpu = struct {
19001939 .xsaveopt,
19011940 }),
19021941 };
1903 pub const _i386 = CpuModel{
1904 .name = "_i386",
1905 .llvm_name = "i386",
1906 .features = featureSet(&[_]Feature{
1907 .slow_unaligned_mem_16,
1908 .vzeroupper,
1909 .x87,
1910 }),
1911 };
1912 pub const _i486 = CpuModel{
1913 .name = "_i486",
1914 .llvm_name = "i486",
1915 .features = featureSet(&[_]Feature{
1916 .slow_unaligned_mem_16,
1917 .vzeroupper,
1918 .x87,
1919 }),
1920 };
1921 pub const _i586 = CpuModel{
1922 .name = "_i586",
1923 .llvm_name = "i586",
1924 .features = featureSet(&[_]Feature{
1925 .cx8,
1926 .slow_unaligned_mem_16,
1927 .vzeroupper,
1928 .x87,
1929 }),
1930 };
1931 pub const _i686 = CpuModel{
1932 .name = "_i686",
1933 .llvm_name = "i686",
1934 .features = featureSet(&[_]Feature{
1935 .cmov,
1936 .cx8,
1937 .slow_unaligned_mem_16,
1938 .vzeroupper,
1939 .x87,
1940 }),
1941 };
19421942 pub const icelake_client = CpuModel{
19431943 .name = "icelake_client",
19441944 .llvm_name = "icelake-client",
......@@ -2341,32 +2341,6 @@ pub const cpu = struct {
23412341 .x87,
23422342 }),
23432343 };
2344 pub const pentium_m = CpuModel{
2345 .name = "pentium_m",
2346 .llvm_name = "pentium-m",
2347 .features = featureSet(&[_]Feature{
2348 .cmov,
2349 .cx8,
2350 .fxsr,
2351 .mmx,
2352 .nopl,
2353 .slow_unaligned_mem_16,
2354 .sse2,
2355 .vzeroupper,
2356 .x87,
2357 }),
2358 };
2359 pub const pentium_mmx = CpuModel{
2360 .name = "pentium_mmx",
2361 .llvm_name = "pentium-mmx",
2362 .features = featureSet(&[_]Feature{
2363 .cx8,
2364 .mmx,
2365 .slow_unaligned_mem_16,
2366 .vzeroupper,
2367 .x87,
2368 }),
2369 };
23702344 pub const pentium2 = CpuModel{
23712345 .name = "pentium2",
23722346 .llvm_name = "pentium2",
......@@ -2441,6 +2415,32 @@ pub const cpu = struct {
24412415 .x87,
24422416 }),
24432417 };
2418 pub const pentium_m = CpuModel{
2419 .name = "pentium_m",
2420 .llvm_name = "pentium-m",
2421 .features = featureSet(&[_]Feature{
2422 .cmov,
2423 .cx8,
2424 .fxsr,
2425 .mmx,
2426 .nopl,
2427 .slow_unaligned_mem_16,
2428 .sse2,
2429 .vzeroupper,
2430 .x87,
2431 }),
2432 };
2433 pub const pentium_mmx = CpuModel{
2434 .name = "pentium_mmx",
2435 .llvm_name = "pentium-mmx",
2436 .features = featureSet(&[_]Feature{
2437 .cx8,
2438 .mmx,
2439 .slow_unaligned_mem_16,
2440 .vzeroupper,
2441 .x87,
2442 }),
2443 };
24442444 pub const pentiumpro = CpuModel{
24452445 .name = "pentiumpro",
24462446 .llvm_name = "pentiumpro",
......@@ -2894,21 +2894,21 @@ pub const cpu = struct {
28942894 .x87,
28952895 }),
28962896 };
2897 pub const winchip_c6 = CpuModel{
2898 .name = "winchip_c6",
2899 .llvm_name = "winchip-c6",
2897 pub const winchip2 = CpuModel{
2898 .name = "winchip2",
2899 .llvm_name = "winchip2",
29002900 .features = featureSet(&[_]Feature{
2901 .mmx,
2901 .@"3dnow",
29022902 .slow_unaligned_mem_16,
29032903 .vzeroupper,
29042904 .x87,
29052905 }),
29062906 };
2907 pub const winchip2 = CpuModel{
2908 .name = "winchip2",
2909 .llvm_name = "winchip2",
2907 pub const winchip_c6 = CpuModel{
2908 .name = "winchip_c6",
2909 .llvm_name = "winchip-c6",
29102910 .features = featureSet(&[_]Feature{
2911 .@"3dnow",
2911 .mmx,
29122912 .slow_unaligned_mem_16,
29132913 .vzeroupper,
29142914 .x87,
tools/update_cpu_features.zig+205-136
......@@ -4,25 +4,36 @@ const mem = std.mem;
44const json = std.json;
55const assert = std.debug.assert;
66
7// All references to other features are based on "zig name" as the key.
8
79const FeatureOverride = struct {
810 llvm_name: []const u8,
911 omit: bool = false,
1012 zig_name: ?[]const u8 = null,
1113 desc: ?[]const u8 = null,
14 extra_deps: []const []const u8 = &.{},
1215};
1316
14const ExtraCpu = struct {
17const Cpu = struct {
1518 llvm_name: ?[]const u8,
1619 zig_name: []const u8,
1720 features: []const []const u8,
1821};
1922
23const Feature = struct {
24 llvm_name: ?[]const u8 = null,
25 zig_name: []const u8,
26 desc: []const u8,
27 deps: []const []const u8,
28};
29
2030const LlvmTarget = struct {
2131 zig_name: []const u8,
2232 llvm_name: []const u8,
2333 td_name: []const u8,
2434 feature_overrides: []const FeatureOverride = &.{},
25 extra_cpus: []const ExtraCpu = &.{},
35 extra_cpus: []const Cpu = &.{},
36 extra_features: []const Feature = &.{},
2637 branch_quota: ?usize = null,
2738};
2839
......@@ -54,6 +65,25 @@ const llvm_targets = [_]LlvmTarget{
5465 .llvm_name = "neoversev1",
5566 .zig_name = "neoverse_v1",
5667 },
68 .{
69 .llvm_name = "exynosm3",
70 .zig_name = "exynos_m3",
71 },
72 .{
73 .llvm_name = "exynosm4",
74 .zig_name = "exynos_m4",
75 },
76 .{
77 .llvm_name = "v8.1a",
78 .extra_deps = &.{"v8a"},
79 },
80 },
81 .extra_features = &.{
82 .{
83 .zig_name = "v8a",
84 .desc = "Support ARM v8a instructions",
85 .deps = &.{ "fp_armv8", "neon" },
86 },
5787 },
5888 },
5989 .{
......@@ -331,8 +361,9 @@ fn processOneTarget(job: Job) anyerror!void {
331361 render_progress.activate();
332362
333363 const root_map = &tree.root.Object;
334 var all_features = std.ArrayList(*json.ObjectMap).init(arena);
335 var all_cpus = std.ArrayList(*json.ObjectMap).init(arena);
364 var features_table = std.StringHashMap(Feature).init(arena);
365 var all_features = std.ArrayList(Feature).init(arena);
366 var all_cpus = std.ArrayList(Cpu).init(arena);
336367 {
337368 var it = root_map.iterator();
338369 root_it: while (it.next()) |kv| {
......@@ -342,23 +373,101 @@ fn processOneTarget(job: Job) anyerror!void {
342373 if (hasSuperclass(&kv.value.Object, "SubtargetFeature")) {
343374 const llvm_name = kv.value.Object.get("Name").?.String;
344375 if (llvm_name.len == 0) continue;
376
377 var zig_name = (try llvmNameToZigName(arena, llvm_target, llvm_name)) orelse
378 continue :root_it;
379 var desc = kv.value.Object.get("Desc").?.String;
380 var deps = std.ArrayList([]const u8).init(arena);
381 const implies = kv.value.Object.get("Implies").?.Array;
382 for (implies.items) |imply| {
383 const other_key = imply.Object.get("def").?.String;
384 const other_obj = &root_map.getEntry(other_key).?.value.Object;
385 const other_llvm_name = other_obj.get("Name").?.String;
386 const other_zig_name = (try llvmNameToZigName(arena, llvm_target, other_llvm_name)) orelse continue;
387 try deps.append(other_zig_name);
388 }
345389 for (llvm_target.feature_overrides) |feature_override| {
346390 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
347391 if (feature_override.omit) {
348392 continue :root_it;
349393 }
394 if (feature_override.zig_name) |override_name| {
395 zig_name = override_name;
396 }
397 if (feature_override.desc) |override_desc| {
398 desc = override_desc;
399 }
400 for (feature_override.extra_deps) |extra_dep| {
401 try deps.append(extra_dep);
402 }
403 break;
350404 }
351405 }
352
353 try all_features.append(&kv.value.Object);
406 const feature: Feature = .{
407 .llvm_name = llvm_name,
408 .zig_name = zig_name,
409 .desc = desc,
410 .deps = deps.items,
411 };
412 try features_table.put(zig_name, feature);
413 try all_features.append(feature);
354414 }
355415 if (hasSuperclass(&kv.value.Object, "Processor")) {
356 try all_cpus.append(&kv.value.Object);
416 const llvm_name = kv.value.Object.get("Name").?.String;
417 if (llvm_name.len == 0) continue;
418
419 var zig_name = (try llvmNameToZigName(arena, llvm_target, llvm_name)) orelse
420 continue :root_it;
421 var deps = std.ArrayList([]const u8).init(arena);
422 const features = kv.value.Object.get("Features").?.Array;
423 for (features.items) |feature| {
424 const feature_key = feature.Object.get("def").?.String;
425 const feature_obj = &root_map.getEntry(feature_key).?.value.Object;
426 const feature_llvm_name = feature_obj.get("Name").?.String;
427 if (feature_llvm_name.len == 0) continue;
428 const feature_zig_name = (try llvmNameToZigName(arena, llvm_target, feature_llvm_name)) orelse continue;
429 try deps.append(feature_zig_name);
430 }
431 const tune_features = kv.value.Object.get("TuneFeatures").?.Array;
432 for (tune_features.items) |feature| {
433 const feature_key = feature.Object.get("def").?.String;
434 const feature_obj = &root_map.getEntry(feature_key).?.value.Object;
435 const feature_llvm_name = feature_obj.get("Name").?.String;
436 if (feature_llvm_name.len == 0) continue;
437 const feature_zig_name = (try llvmNameToZigName(arena, llvm_target, feature_llvm_name)) orelse continue;
438 try deps.append(feature_zig_name);
439 }
440 for (llvm_target.feature_overrides) |feature_override| {
441 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
442 if (feature_override.omit) {
443 continue :root_it;
444 }
445 if (feature_override.zig_name) |override_name| {
446 zig_name = override_name;
447 }
448 for (feature_override.extra_deps) |extra_dep| {
449 try deps.append(extra_dep);
450 }
451 break;
452 }
453 }
454 try all_cpus.append(.{
455 .llvm_name = llvm_name,
456 .zig_name = zig_name,
457 .features = deps.items,
458 });
357459 }
358460 }
359461 }
360 std.sort.sort(*json.ObjectMap, all_features.items, {}, objectLessThan);
361 std.sort.sort(*json.ObjectMap, all_cpus.items, {}, objectLessThan);
462 for (llvm_target.extra_features) |extra_feature| {
463 try features_table.put(extra_feature.zig_name, extra_feature);
464 try all_features.append(extra_feature);
465 }
466 for (llvm_target.extra_cpus) |extra_cpu| {
467 try all_cpus.append(extra_cpu);
468 }
469 std.sort.sort(Feature, all_features.items, {}, featureLessThan);
470 std.sort.sort(Cpu, all_cpus.items, {}, cpuLessThan);
362471
363472 const target_sub_path = try fs.path.join(arena, &.{ "lib", "std", "target" });
364473 var target_dir = try job.zig_src_dir.makeOpenPath(target_sub_path, .{});
......@@ -389,10 +498,8 @@ fn processOneTarget(job: Job) anyerror!void {
389498 \\
390499 );
391500
392 for (all_features.items) |obj| {
393 const llvm_name = obj.get("Name").?.String;
394 const zig_name = try llvmNameToZigName(arena, llvm_target, llvm_name);
395 try w.print(" {},\n", .{std.zig.fmtId(zig_name)});
501 for (all_features.items) |feature| {
502 try w.print(" {},\n", .{std.zig.fmtId(feature.zig_name)});
396503 }
397504
398505 try w.writeAll(
......@@ -413,45 +520,46 @@ fn processOneTarget(job: Job) anyerror!void {
413520 \\
414521 );
415522
416 for (all_features.items) |obj| {
417 const llvm_name = obj.get("Name").?.String;
418 const llvm_description = obj.get("Desc").?.String;
419 const description = for (llvm_target.feature_overrides) |feature_override| {
420 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
421 if (feature_override.desc) |desc| {
422 break desc;
423 }
424 }
425 } else llvm_description;
426 const zig_name = try llvmNameToZigName(arena, llvm_target, llvm_name);
427 try w.print(
428 \\ result[@enumToInt(Feature.{})] = .{{
429 \\ .llvm_name = "{}",
430 \\ .description = "{}",
431 \\ .dependencies = featureSet(&[_]Feature{{
432 ,
433 .{
434 std.zig.fmtId(zig_name),
435 std.zig.fmtEscapes(llvm_name),
436 std.zig.fmtEscapes(description),
437 },
438 );
439 const implies = obj.get("Implies").?.Array;
523 for (all_features.items) |feature| {
524 if (feature.llvm_name) |llvm_name| {
525 try w.print(
526 \\ result[@enumToInt(Feature.{})] = .{{
527 \\ .llvm_name = "{}",
528 \\ .description = "{}",
529 \\ .dependencies = featureSet(&[_]Feature{{
530 ,
531 .{
532 std.zig.fmtId(feature.zig_name),
533 std.zig.fmtEscapes(llvm_name),
534 std.zig.fmtEscapes(feature.desc),
535 },
536 );
537 } else {
538 try w.print(
539 \\ result[@enumToInt(Feature.{})] = .{{
540 \\ .llvm_name = null,
541 \\ .description = "{}",
542 \\ .dependencies = featureSet(&[_]Feature{{
543 ,
544 .{
545 std.zig.fmtId(feature.zig_name),
546 std.zig.fmtEscapes(feature.desc),
547 },
548 );
549 }
440550 var deps_set = std.StringHashMap(void).init(arena);
441 for (implies.items) |imply| {
442 const other_key = imply.Object.get("def").?.String;
443 try deps_set.put(other_key, {});
551 for (feature.deps) |dep| {
552 try deps_set.put(dep, {});
444553 }
445 try pruneFeatures(arena, root_map, &deps_set);
446 var dependencies = std.ArrayList(*json.ObjectMap).init(arena);
554 try pruneFeatures(arena, features_table, &deps_set);
555 var dependencies = std.ArrayList([]const u8).init(arena);
447556 {
448557 var it = deps_set.iterator();
449558 while (it.next()) |entry| {
450 const other_obj = &root_map.getEntry(entry.key).?.value.Object;
451 try dependencies.append(other_obj);
559 try dependencies.append(entry.key);
452560 }
453561 }
454 std.sort.sort(*json.ObjectMap, dependencies.items, {}, objectLessThan);
562 std.sort.sort([]const u8, dependencies.items, {}, asciiLessThan);
455563
456564 if (dependencies.items.len == 0) {
457565 try w.writeAll(
......@@ -462,9 +570,7 @@ fn processOneTarget(job: Job) anyerror!void {
462570 } else {
463571 try w.writeAll("\n");
464572 for (dependencies.items) |dep| {
465 const other_llvm_name = dep.get("Name").?.String;
466 const other_zig_name = try llvmNameToZigName(arena, llvm_target, other_llvm_name);
467 try w.print(" .{},\n", .{std.zig.fmtId(other_zig_name)});
573 try w.print(" .{},\n", .{std.zig.fmtId(dep)});
468574 }
469575 try w.writeAll(
470576 \\ }),
......@@ -485,81 +591,42 @@ fn processOneTarget(job: Job) anyerror!void {
485591 \\pub const cpu = struct {
486592 \\
487593 );
488 for (llvm_target.extra_cpus) |extra_cpu| {
489 try w.print(
490 \\ pub const {} = CpuModel{{
491 \\ .name = "{}",
492 \\
493 , .{
494 std.zig.fmtId(extra_cpu.zig_name),
495 std.zig.fmtEscapes(extra_cpu.zig_name),
496 });
497 if (extra_cpu.llvm_name) |llvm_name| {
498 try w.print(
499 \\ .llvm_name = "{}",
500 \\ .features = featureSet(&[_]Feature{{
501 , .{std.zig.fmtEscapes(llvm_name)});
502 } else {
503 try w.writeAll(
504 \\ .llvm_name = null,
505 \\ .features = featureSet(&[_]Feature{
506 );
507 }
508 if (extra_cpu.features.len == 0) {
509 try w.writeAll(
510 \\}),
511 \\ };
512 \\
513 );
514 } else {
515 try w.writeAll("\n");
516 for (extra_cpu.features) |feature_zig_name| {
517 try w.print(" .{},\n", .{std.zig.fmtId(feature_zig_name)});
518 }
519 try w.writeAll(
520 \\ }),
521 \\ };
522 \\
523 );
524 }
525 }
526 for (all_cpus.items) |obj| {
527 const llvm_name = obj.get("Name").?.String;
594 for (all_cpus.items) |cpu| {
528595 var deps_set = std.StringHashMap(void).init(arena);
529
530 const features = obj.get("Features").?.Array;
531 for (features.items) |feature| {
532 const feature_key = feature.Object.get("def").?.String;
533 try deps_set.put(feature_key, {});
596 for (cpu.features) |feature_zig_name| {
597 try deps_set.put(feature_zig_name, {});
534598 }
535 const tune_features = obj.get("TuneFeatures").?.Array;
536 for (tune_features.items) |feature| {
537 const feature_key = feature.Object.get("def").?.String;
538 try deps_set.put(feature_key, {});
539 }
540 try pruneFeatures(arena, root_map, &deps_set);
541 var cpu_features = std.ArrayList(*json.ObjectMap).init(arena);
599 try pruneFeatures(arena, features_table, &deps_set);
600 var cpu_features = std.ArrayList([]const u8).init(arena);
542601 {
543602 var it = deps_set.iterator();
544603 while (it.next()) |entry| {
545 const feature_obj = &root_map.getEntry(entry.key).?.value.Object;
546 const feature_llvm_name = feature_obj.get("Name").?.String;
547 if (feature_llvm_name.len == 0) continue;
548 try cpu_features.append(feature_obj);
604 try cpu_features.append(entry.key);
549605 }
550606 }
551 std.sort.sort(*json.ObjectMap, cpu_features.items, {}, objectLessThan);
552 const zig_cpu_name = try llvmNameToZigName(arena, llvm_target, llvm_name);
553 try w.print(
554 \\ pub const {} = CpuModel{{
555 \\ .name = "{}",
556 \\ .llvm_name = "{}",
557 \\ .features = featureSet(&[_]Feature{{
558 , .{
559 std.zig.fmtId(zig_cpu_name),
560 std.zig.fmtEscapes(zig_cpu_name),
561 std.zig.fmtEscapes(llvm_name),
562 });
607 std.sort.sort([]const u8, cpu_features.items, {}, asciiLessThan);
608 if (cpu.llvm_name) |llvm_name| {
609 try w.print(
610 \\ pub const {} = CpuModel{{
611 \\ .name = "{}",
612 \\ .llvm_name = "{}",
613 \\ .features = featureSet(&[_]Feature{{
614 , .{
615 std.zig.fmtId(cpu.zig_name),
616 std.zig.fmtEscapes(cpu.zig_name),
617 std.zig.fmtEscapes(llvm_name),
618 });
619 } else {
620 try w.print(
621 \\ pub const {} = CpuModel{{
622 \\ .name = "{}",
623 \\ .llvm_name = null,
624 \\ .features = featureSet(&[_]Feature{{
625 , .{
626 std.zig.fmtId(cpu.zig_name),
627 std.zig.fmtEscapes(cpu.zig_name),
628 });
629 }
563630 if (cpu_features.items.len == 0) {
564631 try w.writeAll(
565632 \\}),
......@@ -568,9 +635,7 @@ fn processOneTarget(job: Job) anyerror!void {
568635 );
569636 } else {
570637 try w.writeAll("\n");
571 for (cpu_features.items) |feature_obj| {
572 const feature_llvm_name = feature_obj.get("Name").?.String;
573 const feature_zig_name = try llvmNameToZigName(arena, llvm_target, feature_llvm_name);
638 for (cpu_features.items) |feature_zig_name| {
574639 try w.print(" .{},\n", .{std.zig.fmtId(feature_zig_name)});
575640 }
576641 try w.writeAll(
......@@ -602,20 +667,26 @@ fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn {
602667 std.process.exit(code);
603668}
604669
605fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
606 const a_key = a.get("Name").?.String;
607 const b_key = b.get("Name").?.String;
608 return std.ascii.lessThanIgnoreCase(a_key, b_key);
670fn featureLessThan(context: void, a: Feature, b: Feature) bool {
671 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name);
672}
673
674fn cpuLessThan(context: void, a: Cpu, b: Cpu) bool {
675 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name);
676}
677
678fn asciiLessThan(context: void, a: []const u8, b: []const u8) bool {
679 return std.ascii.lessThanIgnoreCase(a, b);
609680}
610681
611682fn llvmNameToZigName(
612683 arena: *mem.Allocator,
613684 llvm_target: LlvmTarget,
614685 llvm_name: []const u8,
615) ![]const u8 {
686) !?[]const u8 {
616687 for (llvm_target.feature_overrides) |feature_override| {
617688 if (mem.eql(u8, feature_override.llvm_name, llvm_name)) {
618 assert(!feature_override.omit);
689 if (feature_override.omit) return null;
619690 return feature_override.zig_name orelse break;
620691 }
621692 }
......@@ -640,7 +711,7 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool {
640711
641712fn pruneFeatures(
642713 arena: *mem.Allocator,
643 root_map: *const json.ObjectMap,
714 features_table: std.StringHashMap(Feature),
644715 deps_set: *std.StringHashMap(void),
645716) !void {
646717 // For each element, recursively iterate over the dependencies and add
......@@ -650,8 +721,8 @@ fn pruneFeatures(
650721 {
651722 var it = deps_set.iterator();
652723 while (it.next()) |entry| {
653 const other_obj = &root_map.getEntry(entry.key).?.value.Object;
654 try walkFeatures(root_map, &deletion_set, other_obj);
724 const feature = features_table.get(entry.key).?;
725 try walkFeatures(features_table, &deletion_set, feature);
655726 }
656727 }
657728 {
......@@ -663,15 +734,13 @@ fn pruneFeatures(
663734}
664735
665736fn walkFeatures(
666 root_map: *const json.ObjectMap,
737 features_table: std.StringHashMap(Feature),
667738 deletion_set: *std.StringHashMap(void),
668 feature: *json.ObjectMap,
739 feature: Feature,
669740) error{OutOfMemory}!void {
670 const implies = feature.get("Implies").?.Array;
671 for (implies.items) |imply| {
672 const other_key = imply.Object.get("def").?.String;
673 try deletion_set.put(other_key, {});
674 const other_obj = &root_map.getEntry(other_key).?.value.Object;
675 try walkFeatures(root_map, deletion_set, other_obj);
741 for (feature.deps) |dep| {
742 try deletion_set.put(dep, {});
743 const other_feature = features_table.get(dep).?;
744 try walkFeatures(features_table, deletion_set, other_feature);
676745 }
677746}