╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ update_cpu_features.zig ──────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
2379 .features = deps.items, 2380 }); 2381 } 2382 } 2383 } 2384 } 2385 } 2386 2387 collate_progress.end(); 2388 } 2389 2390 for (target.extra_features) |extra_feature| { 2391 try features_table.put(extra_feature.zig_name, extra_feature); 2392 try all_features.append(extra_feature); 2393 } 2394 for (target.extra_cpus) |extra_cpu| { 2395 try all_cpus.append(extra_cpu); 2396 } 2397 mem.sort(Feature, all_features.items, {}, featureLessThan); 2398 mem.sort(Cpu, all_cpus.items, {}, cpuLessThan); 2399 2400 const render_progress = progress_node.start("rendering Zig code", 0); 2401 2402 var target_dir = try job.zig_src_dir.openDir(io, "lib/std/Target", .{}); 2403 defer target_dir.close(io); 2404 2405 const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{target.zig_name}); 2406 var zig_code_file = try target_dir.createFile(io, zig_code_basename, .{}); 2407 defer zig_code_file.close(io); 2408 2409 var zig_code_file_buffer: [4096]u8 = undefined; 2410 var zig_code_file_writer = zig_code_file.writer(io, &zig_code_file_buffer); 2411 const w = &zig_code_file_writer.interface; 2412 2413 try w.writeAll( 2414 \\//! This file is auto-generated by tools/update_cpu_features.zig. 2415 \\ 2416 \\const std = @import("../std.zig"); 2417 \\const CpuFeature = std.Target.Cpu.Feature; 2418 \\const CpuModel = std.Target.Cpu.Model; 2419 \\ 2420 \\pub const Feature = enum { 2421 ); 2422 2423 for (all_features.items, 0..) |feature, i| { 2424 try w.print("\n {f},", .{std.zig.fmtIdPU(feature.zig_name)}); 2425 2426 if (i == all_features.items.len - 1) try w.writeAll("\n"); 2427 } 2428 2429 try w.writeAll( 2430 \\}; 2431 \\ 2432 \\pub const featureSet = CpuFeature.FeatureSetFns(Feature).featureSet; 2433 \\pub const featureSetHas = CpuFeature.FeatureSetFns(Feature).featureSetHas; 2434 \\pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; 2435 \\pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; 2436 \\ 2437 \\pub const all_features = blk: { 2438 \\ 2439 ); 2440 if (target.branch_quota) |branch_quota| { 2441 try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota}); 2442 } 2443 try w.writeAll( 2444 \\ const len = @typeInfo(Feature).@"enum".field_names.len; 2445 \\ std.debug.assert(len <= CpuFeature.Set.needed_bit_count); 2446 \\ var result: [len]CpuFeature = undefined; 2447 \\ 2448 ); 2449 2450 for (all_features.items) |feature| { 2451 if (feature.llvm_name) |llvm_name| { 2452 try w.print( 2453 \\ result[@intFromEnum(Feature.{f})] = .{{ 2454 \\ .llvm_name = "{f}", 2455 \\ .description = "{f}", 2456 \\ .dependencies = featureSet(&[_]Feature{{ 2457 , 2458 .{ 2459 std.zig.fmtIdPU(feature.zig_name), 2460 std.zig.fmtString(llvm_name), 2461 std.zig.fmtString(feature.desc), 2462 }, 2463 ); 2464 } else { 2465 try w.print( 2466 \\ result[@intFromEnum(Feature.{f})] = .{{ 2467 \\ .llvm_name = null, 2468 \\ .description = "{f}", 2469 \\ .dependencies = featureSet(&[_]Feature{{ 2470 , 2471 .{ 2472 std.zig.fmtIdPU(feature.zig_name), 2473 std.zig.fmtString(feature.desc), 2474 }, 2475 ); 2476 } 2477 var deps_set = std.StringHashMap(void).init(arena); 2478 for (feature.deps) |dep| { 2479 try putDep(&deps_set, features_table, dep); 2480 } 2481 try pruneFeatures(arena, features_table, &deps_set); 2482 var dependencies = std.array_list.Managed([]const u8).init(arena); 2483 { 2484 var it = deps_set.keyIterator(); 2485 while (it.next()) |key| { 2486 try dependencies.append(key.*); 2487 } 2488 } 2489 mem.sort([]const u8, dependencies.items, {}, asciiLessThan); 2490 2491 if (dependencies.items.len == 0) { 2492 try w.writeAll( 2493 \\}), 2494 \\ }; 2495 \\ 2496 ); 2497 } else { 2498 try w.writeAll("\n"); 2499 for (dependencies.items) |dep| { 2500 try w.print(" .{f},\n", .{std.zig.fmtIdPU(dep)}); 2501 } 2502 try w.writeAll( 2503 \\ }), 2504 \\ }; 2505 \\ 2506 ); 2507 } 2508 } 2509 try w.writeAll( 2510 \\ const ti = @typeInfo(Feature); 2511 \\ for (&result, 0..) |*elem, i| { 2512 \\ elem.index = i; 2513 \\ elem.name = ti.@"enum".field_names[i]; 2514 \\ } 2515 \\ break :blk result; 2516 \\}; 2517 \\ 2518 \\pub const cpu = struct { 2519 \\ 2520 ); 2521 for (all_cpus.items) |cpu| { 2522 var deps_set = std.StringHashMap(void).init(arena); 2523 for (cpu.features) |feature_zig_name| { 2524 try putDep(&deps_set, features_table, feature_zig_name); 2525 } 2526 try pruneFeatures(arena, features_table, &deps_set); 2527 var cpu_features = std.array_list.Managed([]const u8).init(arena); 2528 { 2529 var it = deps_set.keyIterator(); 2530 while (it.next()) |key| { 2531 try cpu_features.append(key.*); 2532 } 2533 } 2534 mem.sort([]const u8, cpu_features.items, {}, asciiLessThan); 2535 if (cpu.llvm_name) |llvm_name| { 2536 try w.print( 2537 \\ pub const {f}: CpuModel = .{{ 2538 \\ .name = "{f}", 2539 \\ .llvm_name = "{f}", 2540 \\ .features = featureSet(&[_]Feature{{ 2541 , .{ 2542 std.zig.fmtId(cpu.zig_name), 2543 std.zig.fmtString(cpu.zig_name), 2544 std.zig.fmtString(llvm_name), 2545 }); 2546 } else { 2547 try w.print( 2548 \\ pub const {f}: CpuModel = .{{ 2549 \\ .name = "{f}", 2550 \\ .llvm_name = null, 2551 \\ .features = featureSet(&[_]Feature{{ 2552 , .{ 2553 std.zig.fmtId(cpu.zig_name), 2554 std.zig.fmtString(cpu.zig_name), 2555 }); 2556 } 2557 if (cpu_features.items.len == 0) { 2558 try w.writeAll( 2559 \\}), 2560 \\ }; 2561 \\ 2562 ); 2563 } else { 2564 try w.writeAll("\n"); 2565 for (cpu_features.items) |feature_zig_name| { 2566 try w.print(" .{f},\n", .{std.zig.fmtIdPU(feature_zig_name)}); 2567 } 2568 try w.writeAll( 2569 \\ }), 2570 \\ }; 2571 \\ 2572 ); 2573 } 2574 } 2575 2576 try w.writeAll( 2577 \\}; 2578 \\ 2579 ); 2580 try w.flush(); 2581 2582 render_progress.end(); 2583 } 2584 2585 fn usageAndExit(arg0: []const u8, code: u8) noreturn { 2586 const stderr = std.debug.lockStderr(&.{}); 2587 const w = &stderr.file_writer.interface; 2588 w.print( 2589 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter] 2590 \\ 2591 \\Updates lib/std/target/<target>.zig from llvm/lib/Target/<Target>/<Target>.td . 2592 \\ 2593 \\On a less beefy system, or when debugging, compile with -fsingle-threaded. 2594 \\ 2595 , .{arg0}) catch std.process.exit(1); 2596 std.process.exit(code); 2597 } 2598 2599 fn featureLessThan(_: void, a: Feature, b: Feature) bool { 2600 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name); 2601 } 2602 2603 fn cpuLessThan(_: void, a: Cpu, b: Cpu) bool { 2604 return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name); 2605 } 2606 2607 fn asciiLessThan(_: void, a: []const u8, b: []const u8) bool { 2608 return std.ascii.lessThanIgnoreCase(a, b); 2609 } 2610 2611 fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 { 2612 const duped = try arena.dupe(u8, llvm_name); 2613 for (duped) |*byte| switch (byte.*) { 2614 '-', '.' => byte.* = '_', 2615 else => continue, 2616 }; 2617 return duped; 2618 } 2619 2620 fn llvmFeatureNameToZigNameOmit( 2621 arena: mem.Allocator, 2622 target: ArchTarget, 2623 llvm_name: []const u8, 2624 ) !?[]const u8 { 2625 for (target.feature_overrides) |feature_override| { 2626 if (mem.eql(u8, feature_override.llvm_name, llvm_name)) { 2627 if (feature_override.omit) return null; 2628 return feature_override.zig_name orelse break; 2629 } 2630 } 2631 return try llvmNameToZigName(arena, llvm_name); 2632 } 2633 2634 fn hasSuperclass(obj: *const json.ObjectMap, class_name: []const u8) bool { 2635 const superclasses_json = obj.get("!superclasses") orelse return false; 2636 for (superclasses_json.array.items) |superclass_json| { 2637 const superclass = superclass_json.string; 2638 if (std.mem.eql(u8, superclass, class_name)) { 2639 return true; 2640 } 2641 } 2642 return false; 2643 } 2644 2645 fn pruneFeatures( 2646 arena: mem.Allocator, 2647 features_table: std.StringHashMap(Feature), 2648 deps_set: *std.StringHashMap(void), 2649 ) !void { 2650 // For each element, recursively iterate over the dependencies and add 2651 // everything we find to a "deletion set". 2652 // Then, iterate over the deletion set and delete all that stuff from `deps_set`. 2653 var deletion_set = std.StringHashMap(void).init(arena); 2654 { 2655 var it = deps_set.keyIterator(); 2656 while (it.next()) |key| { 2657 const feature = features_table.get(key.*).?; 2658 try walkFeatures(features_table, &deletion_set, feature); 2659 } 2660 } 2661 { 2662 var it = deletion_set.keyIterator(); 2663 while (it.next()) |key| { 2664 _ = deps_set.remove(key.*); 2665 } 2666 } 2667 } 2668 2669 fn walkFeatures( 2670 features_table: std.StringHashMap(Feature), 2671 deletion_set: *std.StringHashMap(void), 2672 feature: Feature, 2673 ) error{OutOfMemory}!void { 2674 for (feature.deps) |dep| { 2675 try deletion_set.put(dep, {}); 2676 const other_feature = features_table.get(dep).?; 2677 try walkFeatures(features_table, deletion_set, other_feature); 2678 } 2679 } 2680 2681 fn putDep( 2682 deps_set: *std.StringHashMap(void), 2683 features_table: std.StringHashMap(Feature), 2684 zig_feature_name: []const u8, 2685 ) error{OutOfMemory}!void { 2686 const feature = features_table.get(zig_feature_name).?; 2687 if (feature.flatten) { 2688 for (feature.deps) |dep| { 2689 try putDep(deps_set, features_table, dep); 2690 } 2691 } else { 2692 try deps_set.put(zig_feature_name, {}); 2693 } 2694 } 2695