authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-12-17 15:23:50+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-17 19:17:55+01:00
log5248f0a9095bac52b5a066c0ea0a317439e6cf2f
treee6f47bb71c85694f27c56205f2049dfb406733c2
parentb541a7af1155a984bd41008ea337030d0373e0ea
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

update_cpu_features: Handle targets that don't have LLVM data.


1 files changed, 338 insertions(+), 281 deletions(-)

tools/update_cpu_features.zig+338-281
...@@ -34,10 +34,12 @@ const Feature = struct {...@@ -34,10 +34,12 @@ const Feature = struct {
34 flatten: bool = false,34 flatten: bool = false,
35};35};
3636
37const LlvmTarget = struct {37const ArchTarget = struct {
38 zig_name: []const u8,38 zig_name: []const u8,
39 llvm_name: []const u8,39 llvm: ?struct {
40 td_name: []const u8,40 name: []const u8,
41 td_name: []const u8,
42 },
41 feature_overrides: []const FeatureOverride = &.{},43 feature_overrides: []const FeatureOverride = &.{},
42 extra_cpus: []const Cpu = &.{},44 extra_cpus: []const Cpu = &.{},
43 extra_features: []const Feature = &.{},45 extra_features: []const Feature = &.{},
...@@ -45,11 +47,13 @@ const LlvmTarget = struct {...@@ -45,11 +47,13 @@ const LlvmTarget = struct {
45 branch_quota: ?usize = null,47 branch_quota: ?usize = null,
46};48};
4749
48const llvm_targets = [_]LlvmTarget{50const targets = [_]ArchTarget{
49 .{51 .{
50 .zig_name = "aarch64",52 .zig_name = "aarch64",
51 .llvm_name = "AArch64",53 .llvm = .{
52 .td_name = "AArch64.td",54 .name = "AArch64",
55 .td_name = "AArch64",
56 },
53 .branch_quota = 2000,57 .branch_quota = 2000,
54 .feature_overrides = &.{58 .feature_overrides = &.{
55 .{59 .{
...@@ -391,8 +395,10 @@ const llvm_targets = [_]LlvmTarget{...@@ -391,8 +395,10 @@ const llvm_targets = [_]LlvmTarget{
391 },395 },
392 .{396 .{
393 .zig_name = "amdgcn",397 .zig_name = "amdgcn",
394 .llvm_name = "AMDGPU",398 .llvm = .{
395 .td_name = "AMDGPU.td",399 .name = "AMDGPU",
400 .td_name = "AMDGPU",
401 },
396 .feature_overrides = &.{402 .feature_overrides = &.{
397 .{403 .{
398 .llvm_name = "DumpCode",404 .llvm_name = "DumpCode",
...@@ -418,13 +424,17 @@ const llvm_targets = [_]LlvmTarget{...@@ -418,13 +424,17 @@ const llvm_targets = [_]LlvmTarget{
418 },424 },
419 .{425 .{
420 .zig_name = "arc",426 .zig_name = "arc",
421 .llvm_name = "ARC",427 .llvm = .{
422 .td_name = "ARC.td",428 .name = "ARC",
429 .td_name = "ARC",
430 },
423 },431 },
424 .{432 .{
425 .zig_name = "arm",433 .zig_name = "arm",
426 .llvm_name = "ARM",434 .llvm = .{
427 .td_name = "ARM.td",435 .name = "ARM",
436 .td_name = "ARM",
437 },
428 .branch_quota = 10000,438 .branch_quota = 10000,
429 .feature_overrides = &.{439 .feature_overrides = &.{
430 .{440 .{
...@@ -928,66 +938,90 @@ const llvm_targets = [_]LlvmTarget{...@@ -928,66 +938,90 @@ const llvm_targets = [_]LlvmTarget{
928 },938 },
929 .{939 .{
930 .zig_name = "avr",940 .zig_name = "avr",
931 .llvm_name = "AVR",941 .llvm = .{
932 .td_name = "AVR.td",942 .name = "AVR",
943 .td_name = "AVR",
944 },
933 },945 },
934 .{946 .{
935 .zig_name = "bpf",947 .zig_name = "bpf",
936 .llvm_name = "BPF",948 .llvm = .{
937 .td_name = "BPF.td",949 .name = "BPF",
950 .td_name = "BPF",
951 },
938 },952 },
939 .{953 .{
940 .zig_name = "csky",954 .zig_name = "csky",
941 .llvm_name = "CSKY",955 .llvm = .{
942 .td_name = "CSKY.td",956 .name = "CSKY",
957 .td_name = "CSKY",
958 },
943 },959 },
944 .{960 .{
945 .zig_name = "hexagon",961 .zig_name = "hexagon",
946 .llvm_name = "Hexagon",962 .llvm = .{
947 .td_name = "Hexagon.td",963 .name = "Hexagon",
964 .td_name = "Hexagon",
965 },
948 },966 },
949 .{967 .{
950 .zig_name = "lanai",968 .zig_name = "lanai",
951 .llvm_name = "Lanai",969 .llvm = .{
952 .td_name = "Lanai.td",970 .name = "Lanai",
971 .td_name = "Lanai",
972 },
953 },973 },
954 .{974 .{
955 .zig_name = "loongarch",975 .zig_name = "loongarch",
956 .llvm_name = "LoongArch",976 .llvm = .{
957 .td_name = "LoongArch.td",977 .name = "LoongArch",
978 .td_name = "LoongArch",
979 },
958 },980 },
959 .{981 .{
960 .zig_name = "m68k",982 .zig_name = "m68k",
961 .llvm_name = "M68k",983 .llvm = .{
962 .td_name = "M68k.td",984 .name = "M68k",
985 .td_name = "M68k",
986 },
963 },987 },
964 .{988 .{
965 .zig_name = "msp430",989 .zig_name = "msp430",
966 .llvm_name = "MSP430",990 .llvm = .{
967 .td_name = "MSP430.td",991 .name = "MSP430",
992 .td_name = "MSP430",
993 },
968 },994 },
969 .{995 .{
970 .zig_name = "mips",996 .zig_name = "mips",
971 .llvm_name = "Mips",997 .llvm = .{
972 .td_name = "Mips.td",998 .name = "Mips",
999 .td_name = "Mips",
1000 },
973 },1001 },
974 .{1002 .{
975 .zig_name = "nvptx",1003 .zig_name = "nvptx",
976 .llvm_name = "NVPTX",1004 .llvm = .{
977 .td_name = "NVPTX.td",1005 .name = "NVPTX",
1006 .td_name = "NVPTX",
1007 },
978 },1008 },
979 .{1009 .{
980 .zig_name = "powerpc",1010 .zig_name = "powerpc",
981 .llvm_name = "PowerPC",1011 .llvm = .{
982 .td_name = "PPC.td",1012 .name = "PowerPC",
1013 .td_name = "PPC",
1014 },
983 .omit_cpus = &.{1015 .omit_cpus = &.{
984 "ppc32",1016 "ppc32",
985 },1017 },
986 },1018 },
987 .{1019 .{
988 .zig_name = "riscv",1020 .zig_name = "riscv",
989 .llvm_name = "RISCV",1021 .llvm = .{
990 .td_name = "RISCV.td",1022 .name = "RISCV",
1023 .td_name = "RISCV",
1024 },
991 .branch_quota = 2000,1025 .branch_quota = 2000,
992 .feature_overrides = &.{1026 .feature_overrides = &.{
993 .{1027 .{
...@@ -1010,29 +1044,38 @@ const llvm_targets = [_]LlvmTarget{...@@ -1010,29 +1044,38 @@ const llvm_targets = [_]LlvmTarget{
1010 },1044 },
1011 .{1045 .{
1012 .zig_name = "sparc",1046 .zig_name = "sparc",
1013 .llvm_name = "Sparc",1047 .llvm = .{
1014 .td_name = "Sparc.td",1048 .name = "Sparc",
1049 .td_name = "Sparc",
1050 },
1015 },1051 },
1016 // TODO: merge tools/update_spirv_features.zig into this script1052 // TODO: merge tools/update_spirv_features.zig into this script
1017 //.{1053 //.{
1018 // .zig_name = "spirv",1054 // .zig_name = "spirv",
1019 // .llvm_name = "SPIRV",1055 // .llvm = .{
1020 // .td_name = "SPIRV.td",1056 // .name = "SPIRV",
1057 // },
1021 //},1058 //},
1022 .{1059 .{
1023 .zig_name = "s390x",1060 .zig_name = "s390x",
1024 .llvm_name = "SystemZ",1061 .llvm = .{
1025 .td_name = "SystemZ.td",1062 .name = "SystemZ",
1063 .td_name = "SystemZ",
1064 },
1026 },1065 },
1027 .{1066 .{
1028 .zig_name = "ve",1067 .zig_name = "ve",
1029 .llvm_name = "VE",1068 .llvm = .{
1030 .td_name = "VE.td",1069 .name = "VE",
1070 .td_name = "VE",
1071 },
1031 },1072 },
1032 .{1073 .{
1033 .zig_name = "wasm",1074 .zig_name = "wasm",
1034 .llvm_name = "WebAssembly",1075 .llvm = .{
1035 .td_name = "WebAssembly.td",1076 .name = "WebAssembly",
1077 .td_name = "WebAssembly",
1078 },
1036 .extra_features = &.{1079 .extra_features = &.{
1037 .{1080 .{
1038 .zig_name = "nontrapping_bulk_memory_len0",1081 .zig_name = "nontrapping_bulk_memory_len0",
...@@ -1057,8 +1100,10 @@ const llvm_targets = [_]LlvmTarget{...@@ -1057,8 +1100,10 @@ const llvm_targets = [_]LlvmTarget{
1057 },1100 },
1058 .{1101 .{
1059 .zig_name = "x86",1102 .zig_name = "x86",
1060 .llvm_name = "X86",1103 .llvm = .{
1061 .td_name = "X86.td",1104 .name = "X86",
1105 .td_name = "X86",
1106 },
1062 .feature_overrides = &.{1107 .feature_overrides = &.{
1063 .{1108 .{
1064 .llvm_name = "64bit-mode",1109 .llvm_name = "64bit-mode",
...@@ -1362,13 +1407,17 @@ const llvm_targets = [_]LlvmTarget{...@@ -1362,13 +1407,17 @@ const llvm_targets = [_]LlvmTarget{
1362 },1407 },
1363 .{1408 .{
1364 .zig_name = "xcore",1409 .zig_name = "xcore",
1365 .llvm_name = "XCore",1410 .llvm = .{
1366 .td_name = "XCore.td",1411 .name = "XCore",
1412 .td_name = "XCore",
1413 },
1367 },1414 },
1368 .{1415 .{
1369 .zig_name = "xtensa",1416 .zig_name = "xtensa",
1370 .llvm_name = "Xtensa",1417 .llvm = .{
1371 .td_name = "Xtensa.td",1418 .name = "Xtensa",
1419 .td_name = "Xtensa",
1420 },
1372 },1421 },
1373};1422};
13741423
...@@ -1413,33 +1462,33 @@ pub fn main() anyerror!void {...@@ -1413,33 +1462,33 @@ pub fn main() anyerror!void {
1413 var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});1462 var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});
1414 defer zig_src_dir.close();1463 defer zig_src_dir.close();
14151464
1416 const root_progress = std.Progress.start(.{ .estimated_total_items = llvm_targets.len });1465 const root_progress = std.Progress.start(.{ .estimated_total_items = targets.len });
1417 defer root_progress.end();1466 defer root_progress.end();
14181467
1419 if (builtin.single_threaded) {1468 if (builtin.single_threaded) {
1420 for (llvm_targets) |llvm_target| {1469 for (targets) |target| {
1421 if (filter) |zig_name| if (!std.mem.eql(u8, llvm_target.zig_name, zig_name)) continue;1470 if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
1422 try processOneTarget(.{1471 try processOneTarget(.{
1423 .llvm_tblgen_exe = llvm_tblgen_exe,1472 .llvm_tblgen_exe = llvm_tblgen_exe,
1424 .llvm_src_root = llvm_src_root,1473 .llvm_src_root = llvm_src_root,
1425 .zig_src_dir = zig_src_dir,1474 .zig_src_dir = zig_src_dir,
1426 .root_progress = root_progress,1475 .root_progress = root_progress,
1427 .llvm_target = llvm_target,1476 .target = target,
1428 });1477 });
1429 }1478 }
1430 } else {1479 } else {
1431 var pool: std.Thread.Pool = undefined;1480 var pool: std.Thread.Pool = undefined;
1432 try pool.init(.{ .allocator = arena, .n_jobs = llvm_targets.len });1481 try pool.init(.{ .allocator = arena, .n_jobs = targets.len });
1433 defer pool.deinit();1482 defer pool.deinit();
14341483
1435 for (llvm_targets) |llvm_target| {1484 for (targets) |target| {
1436 if (filter) |zig_name| if (!std.mem.eql(u8, llvm_target.zig_name, zig_name)) continue;1485 if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
1437 const job = Job{1486 const job = Job{
1438 .llvm_tblgen_exe = llvm_tblgen_exe,1487 .llvm_tblgen_exe = llvm_tblgen_exe,
1439 .llvm_src_root = llvm_src_root,1488 .llvm_src_root = llvm_src_root,
1440 .zig_src_dir = zig_src_dir,1489 .zig_src_dir = zig_src_dir,
1441 .root_progress = root_progress,1490 .root_progress = root_progress,
1442 .llvm_target = llvm_target,1491 .target = target,
1443 };1492 };
1444 try pool.spawn(processOneTarget, .{job});1493 try pool.spawn(processOneTarget, .{job});
1445 }1494 }
...@@ -1451,162 +1500,147 @@ const Job = struct {...@@ -1451,162 +1500,147 @@ const Job = struct {
1451 llvm_src_root: []const u8,1500 llvm_src_root: []const u8,
1452 zig_src_dir: std.fs.Dir,1501 zig_src_dir: std.fs.Dir,
1453 root_progress: std.Progress.Node,1502 root_progress: std.Progress.Node,
1454 llvm_target: LlvmTarget,1503 target: ArchTarget,
1455};1504};
14561505
1457fn processOneTarget(job: Job) void {1506fn processOneTarget(job: Job) void {
1458 errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)});1507 errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)});
1459 const llvm_target = job.llvm_target;1508 const target = job.target;
14601509
1461 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);1510 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
1462 defer arena_state.deinit();1511 defer arena_state.deinit();
1463 const arena = arena_state.allocator();1512 const arena = arena_state.allocator();
14641513
1465 const progress_node = job.root_progress.start(llvm_target.zig_name, 3);1514 const progress_node = job.root_progress.start(target.zig_name, 3);
1466 defer progress_node.end();1515 defer progress_node.end();
14671516
1468 const tblgen_progress = progress_node.start("running llvm-tblgen", 0);1517 var features_table = std.StringHashMap(Feature).init(arena);
14691518 var all_features = std.ArrayList(Feature).init(arena);
1470 const child_args = [_][]const u8{1519 var all_cpus = std.ArrayList(Cpu).init(arena);
1471 job.llvm_tblgen_exe,
1472 "--dump-json",
1473 try std.fmt.allocPrint(arena, "{s}/llvm/lib/Target/{s}/{s}", .{
1474 job.llvm_src_root,
1475 llvm_target.llvm_name,
1476 llvm_target.td_name,
1477 }),
1478 try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{job.llvm_src_root}),
1479 try std.fmt.allocPrint(arena, "-I={s}/llvm/lib/Target/{s}", .{
1480 job.llvm_src_root, llvm_target.llvm_name,
1481 }),
1482 };
14831520
1484 const child_result = try std.process.Child.run(.{1521 if (target.llvm) |llvm| {
1485 .allocator = arena,1522 const tblgen_progress = progress_node.start("running llvm-tblgen", 0);
1486 .argv = &child_args,
1487 .max_output_bytes = 500 * 1024 * 1024,
1488 });
1489 tblgen_progress.end();
1490 if (child_result.stderr.len != 0) {
1491 std.debug.print("{s}\n", .{child_result.stderr});
1492 }
14931523
1494 const json_text = switch (child_result.term) {1524 const child_args = [_][]const u8{
1495 .Exited => |code| if (code == 0) child_result.stdout else {1525 job.llvm_tblgen_exe,
1496 std.debug.print("llvm-tblgen exited with code {d}\n", .{code});1526 "--dump-json",
1497 std.process.exit(1);1527 try std.fmt.allocPrint(arena, "{s}/llvm/lib/Target/{s}/{s}.td", .{
1498 },1528 job.llvm_src_root,
1499 else => {1529 llvm.name,
1500 std.debug.print("llvm-tblgen crashed\n", .{});1530 llvm.td_name,
1501 std.process.exit(1);1531 }),
1502 },1532 try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{job.llvm_src_root}),
1503 };1533 try std.fmt.allocPrint(arena, "-I={s}/llvm/lib/Target/{s}", .{
1534 job.llvm_src_root, llvm.name,
1535 }),
1536 };
15041537
1505 const json_parse_progress = progress_node.start("parsing JSON", 0);1538 const child_result = try std.process.Child.run(.{
1539 .allocator = arena,
1540 .argv = &child_args,
1541 .max_output_bytes = 500 * 1024 * 1024,
1542 });
1543 tblgen_progress.end();
1544 if (child_result.stderr.len != 0) {
1545 std.debug.print("{s}\n", .{child_result.stderr});
1546 }
15061547
1507 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});1548 const json_text = switch (child_result.term) {
1508 defer parsed.deinit();1549 .Exited => |code| if (code == 0) child_result.stdout else {
1509 const root_map = &parsed.value.object;1550 std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
1510 json_parse_progress.end();1551 std.process.exit(1);
1552 },
1553 else => {
1554 std.debug.print("llvm-tblgen crashed\n", .{});
1555 std.process.exit(1);
1556 },
1557 };
15111558
1512 const render_progress = progress_node.start("rendering Zig code", 0);1559 const json_parse_progress = progress_node.start("parsing JSON", 0);
15131560
1514 // So far, LLVM only has a few aliases for the same CPU.1561 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
1515 var cpu_aliases = std.StringHashMap(std.SegmentedList(struct {1562 defer parsed.deinit();
1516 llvm: []const u8,1563 const root_map = &parsed.value.object;
1517 zig: []const u8,1564 json_parse_progress.end();
1518 }, 4)).init(arena);
15191565
1520 {1566 const collate_progress = progress_node.start("collating LLVM data", 0);
1521 var it = root_map.iterator();1567
1522 while (it.next()) |kv| {1568 // So far, LLVM only has a few aliases for the same CPU.
1523 if (kv.key_ptr.len == 0) continue;1569 var cpu_aliases = std.StringHashMap(std.SegmentedList(struct {
1524 if (kv.key_ptr.*[0] == '!') continue;1570 llvm: []const u8,
1525 if (kv.value_ptr.* != .object) continue;1571 zig: []const u8,
1526 if (hasSuperclass(&kv.value_ptr.object, "ProcessorAlias")) {1572 }, 4)).init(arena);
1527 // Note that `Name` is actually the alias, while `Alias` is the name that will have1573
1528 // a full `Processor` object defined.1574 {
1529 const llvm_alias = kv.value_ptr.object.get("Name").?.string;1575 var it = root_map.iterator();
1530 const llvm_name = kv.value_ptr.object.get("Alias").?.string;1576 while (it.next()) |kv| {
15311577 if (kv.key_ptr.len == 0) continue;
1532 const gop = try cpu_aliases.getOrPut(try llvmNameToZigName(arena, llvm_name));1578 if (kv.key_ptr.*[0] == '!') continue;
15331579 if (kv.value_ptr.* != .object) continue;
1534 if (!gop.found_existing) gop.value_ptr.* = .{};1580 if (hasSuperclass(&kv.value_ptr.object, "ProcessorAlias")) {
15351581 // Note that `Name` is actually the alias, while `Alias` is the name that will have
1536 try gop.value_ptr.append(arena, .{1582 // a full `Processor` object defined.
1537 .llvm = llvm_alias,1583 const llvm_alias = kv.value_ptr.object.get("Name").?.string;
1538 .zig = try llvmNameToZigName(arena, llvm_alias),1584 const llvm_name = kv.value_ptr.object.get("Alias").?.string;
1539 });1585
1586 const gop = try cpu_aliases.getOrPut(try llvmNameToZigName(arena, llvm_name));
1587
1588 if (!gop.found_existing) gop.value_ptr.* = .{};
1589
1590 try gop.value_ptr.append(arena, .{
1591 .llvm = llvm_alias,
1592 .zig = try llvmNameToZigName(arena, llvm_alias),
1593 });
1594 }
1540 }1595 }
1541 }1596 }
1542 }
15431597
1544 var features_table = std.StringHashMap(Feature).init(arena);1598 {
1545 var all_features = std.ArrayList(Feature).init(arena);1599 var it = root_map.iterator();
1546 var all_cpus = std.ArrayList(Cpu).init(arena);1600 while (it.next()) |kv| {
1547 {1601 if (kv.key_ptr.len == 0) continue;
1548 var it = root_map.iterator();1602 if (kv.key_ptr.*[0] == '!') continue;
1549 while (it.next()) |kv| {1603 if (kv.value_ptr.* != .object) continue;
1550 if (kv.key_ptr.len == 0) continue;1604 if (hasSuperclass(&kv.value_ptr.object, "SubtargetFeature")) {
1551 if (kv.key_ptr.*[0] == '!') continue;1605 const llvm_name = kv.value_ptr.object.get("Name").?.string;
1552 if (kv.value_ptr.* != .object) continue;1606 if (llvm_name.len == 0) continue;
1553 if (hasSuperclass(&kv.value_ptr.object, "SubtargetFeature")) {1607
1554 const llvm_name = kv.value_ptr.object.get("Name").?.string;1608 var zig_name = try llvmNameToZigName(arena, llvm_name);
1555 if (llvm_name.len == 0) continue;1609 var desc = kv.value_ptr.object.get("Desc").?.string;
15561610 var deps = std.ArrayList([]const u8).init(arena);
1557 var zig_name = try llvmNameToZigName(arena, llvm_name);1611 var omit = false;
1558 var desc = kv.value_ptr.object.get("Desc").?.string;1612 var flatten = false;
1559 var deps = std.ArrayList([]const u8).init(arena);1613 var omit_deps: []const []const u8 = &.{};
1560 var omit = false;1614 var extra_deps: []const []const u8 = &.{};
1561 var flatten = false;1615 for (target.feature_overrides) |feature_override| {
1562 var omit_deps: []const []const u8 = &.{};1616 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
1563 var extra_deps: []const []const u8 = &.{};1617 if (feature_override.omit) {
1564 for (llvm_target.feature_overrides) |feature_override| {1618 // Still put the feature into the table so that we can
1565 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {1619 // expand dependencies for the feature overrides marked `flatten`.
1566 if (feature_override.omit) {1620 omit = true;
1567 // Still put the feature into the table so that we can1621 }
1568 // expand dependencies for the feature overrides marked `flatten`.1622 if (feature_override.flatten) {
1569 omit = true;1623 flatten = true;
1570 }1624 }
1571 if (feature_override.flatten) {1625 if (feature_override.zig_name) |override_name| {
1572 flatten = true;1626 zig_name = override_name;
1573 }1627 }
1574 if (feature_override.zig_name) |override_name| {1628 if (feature_override.desc) |override_desc| {
1575 zig_name = override_name;1629 desc = override_desc;
1576 }1630 }
1577 if (feature_override.desc) |override_desc| {1631 omit_deps = feature_override.omit_deps;
1578 desc = override_desc;1632 extra_deps = feature_override.extra_deps;
1633 break;
1579 }1634 }
1580 omit_deps = feature_override.omit_deps;
1581 extra_deps = feature_override.extra_deps;
1582 break;
1583 }
1584 }
1585 const implies = kv.value_ptr.object.get("Implies").?.array;
1586 for (implies.items) |imply| {
1587 const other_key = imply.object.get("def").?.string;
1588 const other_obj = root_map.get(other_key).?.object;
1589 const other_llvm_name = other_obj.get("Name").?.string;
1590 const other_zig_name = (try llvmFeatureNameToZigNameOmit(
1591 arena,
1592 llvm_target,
1593 other_llvm_name,
1594 )) orelse continue;
1595 for (omit_deps) |omit_dep| {
1596 if (mem.eql(u8, other_zig_name, omit_dep)) break;
1597 } else {
1598 try deps.append(other_zig_name);
1599 }1635 }
1600 }1636 const implies = kv.value_ptr.object.get("Implies").?.array;
1601 // This is used by AArch64.1637 for (implies.items) |imply| {
1602 if (kv.value_ptr.object.get("DefaultExts")) |exts_val| {1638 const other_key = imply.object.get("def").?.string;
1603 for (exts_val.array.items) |ext| {
1604 const other_key = ext.object.get("def").?.string;
1605 const other_obj = root_map.get(other_key).?.object;1639 const other_obj = root_map.get(other_key).?.object;
1606 const other_llvm_name = other_obj.get("Name").?.string;1640 const other_llvm_name = other_obj.get("Name").?.string;
1607 const other_zig_name = (try llvmFeatureNameToZigNameOmit(1641 const other_zig_name = (try llvmFeatureNameToZigNameOmit(
1608 arena,1642 arena,
1609 llvm_target,1643 target,
1610 other_llvm_name,1644 other_llvm_name,
1611 )) orelse continue;1645 )) orelse continue;
1612 for (omit_deps) |omit_dep| {1646 for (omit_deps) |omit_dep| {
...@@ -1615,118 +1649,141 @@ fn processOneTarget(job: Job) void {...@@ -1615,118 +1649,141 @@ fn processOneTarget(job: Job) void {
1615 try deps.append(other_zig_name);1649 try deps.append(other_zig_name);
1616 }1650 }
1617 }1651 }
1652 // This is used by AArch64.
1653 if (kv.value_ptr.object.get("DefaultExts")) |exts_val| {
1654 for (exts_val.array.items) |ext| {
1655 const other_key = ext.object.get("def").?.string;
1656 const other_obj = root_map.get(other_key).?.object;
1657 const other_llvm_name = other_obj.get("Name").?.string;
1658 const other_zig_name = (try llvmFeatureNameToZigNameOmit(
1659 arena,
1660 target,
1661 other_llvm_name,
1662 )) orelse continue;
1663 for (omit_deps) |omit_dep| {
1664 if (mem.eql(u8, other_zig_name, omit_dep)) break;
1665 } else {
1666 try deps.append(other_zig_name);
1667 }
1668 }
1669 }
1670 for (extra_deps) |extra_dep| {
1671 try deps.append(extra_dep);
1672 }
1673 const feature: Feature = .{
1674 .llvm_name = llvm_name,
1675 .zig_name = zig_name,
1676 .desc = desc,
1677 .deps = deps.items,
1678 .flatten = flatten,
1679 };
1680 try features_table.put(zig_name, feature);
1681 if (!omit and !flatten) {
1682 try all_features.append(feature);
1683 }
1618 }1684 }
1619 for (extra_deps) |extra_dep| {1685 if (hasSuperclass(&kv.value_ptr.object, "Processor")) {
1620 try deps.append(extra_dep);1686 const llvm_name = kv.value_ptr.object.get("Name").?.string;
1621 }1687 if (llvm_name.len == 0) continue;
1622 const feature: Feature = .{1688 const omitted = for (target.omit_cpus) |omit_cpu_name| {
1623 .llvm_name = llvm_name,1689 if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;
1624 .zig_name = zig_name,1690 } else false;
1625 .desc = desc,1691 if (omitted) continue;
1626 .deps = deps.items,1692
1627 .flatten = flatten,1693 var zig_name = try llvmNameToZigName(arena, llvm_name);
1628 };1694 var deps = std.ArrayList([]const u8).init(arena);
1629 try features_table.put(zig_name, feature);1695 var omit_deps: []const []const u8 = &.{};
1630 if (!omit and !flatten) {1696 var extra_deps: []const []const u8 = &.{};
1631 try all_features.append(feature);1697 for (target.feature_overrides) |feature_override| {
1632 }1698 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
1633 }1699 if (feature_override.omit) {
1634 if (hasSuperclass(&kv.value_ptr.object, "Processor")) {1700 continue;
1635 const llvm_name = kv.value_ptr.object.get("Name").?.string;1701 }
1636 if (llvm_name.len == 0) continue;1702 if (feature_override.zig_name) |override_name| {
1637 const omitted = for (llvm_target.omit_cpus) |omit_cpu_name| {1703 zig_name = override_name;
1638 if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;1704 }
1639 } else false;1705 omit_deps = feature_override.omit_deps;
1640 if (omitted) continue;1706 extra_deps = feature_override.extra_deps;
16411707 break;
1642 var zig_name = try llvmNameToZigName(arena, llvm_name);
1643 var deps = std.ArrayList([]const u8).init(arena);
1644 var omit_deps: []const []const u8 = &.{};
1645 var extra_deps: []const []const u8 = &.{};
1646 for (llvm_target.feature_overrides) |feature_override| {
1647 if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
1648 if (feature_override.omit) {
1649 continue;
1650 }1708 }
1651 if (feature_override.zig_name) |override_name| {1709 }
1652 zig_name = override_name;1710 const features = kv.value_ptr.object.get("Features").?.array;
1711 for (features.items) |feature| {
1712 const feature_key = feature.object.get("def").?.string;
1713 const feature_obj = root_map.get(feature_key).?.object;
1714 const feature_llvm_name = feature_obj.get("Name").?.string;
1715 if (feature_llvm_name.len == 0) continue;
1716 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
1717 arena,
1718 target,
1719 feature_llvm_name,
1720 )) orelse continue;
1721 for (omit_deps) |omit_dep| {
1722 if (mem.eql(u8, feature_zig_name, omit_dep)) break;
1723 } else {
1724 try deps.append(feature_zig_name);
1653 }1725 }
1654 omit_deps = feature_override.omit_deps;
1655 extra_deps = feature_override.extra_deps;
1656 break;
1657 }1726 }
1658 }1727 for (extra_deps) |extra_dep| {
1659 const features = kv.value_ptr.object.get("Features").?.array;1728 try deps.append(extra_dep);
1660 for (features.items) |feature| {1729 }
1661 const feature_key = feature.object.get("def").?.string;1730 const tune_features = kv.value_ptr.object.get("TuneFeatures").?.array;
1662 const feature_obj = root_map.get(feature_key).?.object;1731 for (tune_features.items) |feature| {
1663 const feature_llvm_name = feature_obj.get("Name").?.string;1732 const feature_key = feature.object.get("def").?.string;
1664 if (feature_llvm_name.len == 0) continue;1733 const feature_obj = root_map.get(feature_key).?.object;
1665 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(1734 const feature_llvm_name = feature_obj.get("Name").?.string;
1666 arena,1735 if (feature_llvm_name.len == 0) continue;
1667 llvm_target,1736 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
1668 feature_llvm_name,1737 arena,
1669 )) orelse continue;1738 target,
1670 for (omit_deps) |omit_dep| {1739 feature_llvm_name,
1671 if (mem.eql(u8, feature_zig_name, omit_dep)) break;1740 )) orelse continue;
1672 } else {
1673 try deps.append(feature_zig_name);1741 try deps.append(feature_zig_name);
1674 }1742 }
1675 }1743 try all_cpus.append(.{
1676 for (extra_deps) |extra_dep| {1744 .llvm_name = llvm_name,
1677 try deps.append(extra_dep);1745 .zig_name = zig_name,
1678 }1746 .features = deps.items,
1679 const tune_features = kv.value_ptr.object.get("TuneFeatures").?.array;1747 });
1680 for (tune_features.items) |feature| {1748
1681 const feature_key = feature.object.get("def").?.string;1749 if (cpu_aliases.get(zig_name)) |aliases| {
1682 const feature_obj = root_map.get(feature_key).?.object;1750 var alias_it = aliases.constIterator(0);
1683 const feature_llvm_name = feature_obj.get("Name").?.string;1751
1684 if (feature_llvm_name.len == 0) continue;1752 alias_it: while (alias_it.next()) |alias| {
1685 const feature_zig_name = (try llvmFeatureNameToZigNameOmit(1753 for (target.omit_cpus) |omit_cpu_name| {
1686 arena,1754 if (mem.eql(u8, omit_cpu_name, alias.llvm)) continue :alias_it;
1687 llvm_target,1755 }
1688 feature_llvm_name,
1689 )) orelse continue;
1690 try deps.append(feature_zig_name);
1691 }
1692 try all_cpus.append(.{
1693 .llvm_name = llvm_name,
1694 .zig_name = zig_name,
1695 .features = deps.items,
1696 });
1697
1698 if (cpu_aliases.get(zig_name)) |aliases| {
1699 var alias_it = aliases.constIterator(0);
1700
1701 alias_it: while (alias_it.next()) |alias| {
1702 for (llvm_target.omit_cpus) |omit_cpu_name| {
1703 if (mem.eql(u8, omit_cpu_name, alias.llvm)) continue :alias_it;
1704 }
17051756
1706 try all_cpus.append(.{1757 try all_cpus.append(.{
1707 .llvm_name = alias.llvm,1758 .llvm_name = alias.llvm,
1708 .zig_name = alias.zig,1759 .zig_name = alias.zig,
1709 .features = deps.items,1760 .features = deps.items,
1710 });1761 });
1762 }
1711 }1763 }
1712 }1764 }
1713 }1765 }
1714 }1766 }
1767
1768 collate_progress.end();
1715 }1769 }
1716 for (llvm_target.extra_features) |extra_feature| {1770
1771 for (target.extra_features) |extra_feature| {
1717 try features_table.put(extra_feature.zig_name, extra_feature);1772 try features_table.put(extra_feature.zig_name, extra_feature);
1718 try all_features.append(extra_feature);1773 try all_features.append(extra_feature);
1719 }1774 }
1720 for (llvm_target.extra_cpus) |extra_cpu| {1775 for (target.extra_cpus) |extra_cpu| {
1721 try all_cpus.append(extra_cpu);1776 try all_cpus.append(extra_cpu);
1722 }1777 }
1723 mem.sort(Feature, all_features.items, {}, featureLessThan);1778 mem.sort(Feature, all_features.items, {}, featureLessThan);
1724 mem.sort(Cpu, all_cpus.items, {}, cpuLessThan);1779 mem.sort(Cpu, all_cpus.items, {}, cpuLessThan);
17251780
1781 const render_progress = progress_node.start("rendering Zig code", 0);
1782
1726 var target_dir = try job.zig_src_dir.openDir("lib/std/Target", .{});1783 var target_dir = try job.zig_src_dir.openDir("lib/std/Target", .{});
1727 defer target_dir.close();1784 defer target_dir.close();
17281785
1729 const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{llvm_target.zig_name});1786 const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{target.zig_name});
1730 var zig_code_file = try target_dir.createFile(zig_code_basename, .{});1787 var zig_code_file = try target_dir.createFile(zig_code_basename, .{});
1731 defer zig_code_file.close();1788 defer zig_code_file.close();
17321789
...@@ -1760,7 +1817,7 @@ fn processOneTarget(job: Job) void {...@@ -1760,7 +1817,7 @@ fn processOneTarget(job: Job) void {
1760 \\pub const all_features = blk: {1817 \\pub const all_features = blk: {
1761 \\1818 \\
1762 );1819 );
1763 if (llvm_target.branch_quota) |branch_quota| {1820 if (target.branch_quota) |branch_quota| {
1764 try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota});1821 try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota});
1765 }1822 }
1766 try w.writeAll(1823 try w.writeAll(
...@@ -1941,10 +1998,10 @@ fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 {...@@ -1941,10 +1998,10 @@ fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 {
19411998
1942fn llvmFeatureNameToZigNameOmit(1999fn llvmFeatureNameToZigNameOmit(
1943 arena: mem.Allocator,2000 arena: mem.Allocator,
1944 llvm_target: LlvmTarget,2001 target: ArchTarget,
1945 llvm_name: []const u8,2002 llvm_name: []const u8,
1946) !?[]const u8 {2003) !?[]const u8 {
1947 for (llvm_target.feature_overrides) |feature_override| {2004 for (target.feature_overrides) |feature_override| {
1948 if (mem.eql(u8, feature_override.llvm_name, llvm_name)) {2005 if (mem.eql(u8, feature_override.llvm_name, llvm_name)) {
1949 if (feature_override.omit) return null;2006 if (feature_override.omit) return null;
1950 return feature_override.zig_name orelse break;2007 return feature_override.zig_name orelse break;