| ... | @@ -539,19 +539,82 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz | ... | @@ -539,19 +539,82 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz |
| 539 | node.context.maybeRefresh(); | 539 | node.context.maybeRefresh(); |
| 540 | } | 540 | } |
| 541 | | 541 | |
| | 542 | fn cpuFeaturesFromLLVM( |
| | 543 | arch: Target.Arch, |
| | 544 | llvm_cpu_name_z: ?[*:0]const u8, |
| | 545 | llvm_cpu_features_opt: ?[*:0]const u8, |
| | 546 | ) !Target.CpuFeatures { |
| | 547 | if (llvm_cpu_name_z) |cpu_name_z| { |
| | 548 | const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z); |
| | 549 | |
| | 550 | for (arch.allCpus()) |cpu| { |
| | 551 | const this_llvm_name = cpu.llvm_name orelse continue; |
| | 552 | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { |
| | 553 | return Target.CpuFeatures{ .cpu = cpu }; |
| | 554 | } |
| | 555 | } |
| | 556 | } |
| | 557 | |
| | 558 | var set = arch.baselineFeatures(); |
| | 559 | const llvm_cpu_features = llvm_cpu_features_opt orelse return Target.CpuFeatures{ |
| | 560 | .features = set, |
| | 561 | }; |
| | 562 | |
| | 563 | var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ","); |
| | 564 | while (it.next()) |decorated_llvm_feat| { |
| | 565 | var op: enum { |
| | 566 | add, |
| | 567 | sub, |
| | 568 | } = undefined; |
| | 569 | var llvm_feat: []const u8 = undefined; |
| | 570 | if (mem.startsWith(u8, decorated_llvm_feat, "+")) { |
| | 571 | op = .add; |
| | 572 | llvm_feat = decorated_llvm_feat[1..]; |
| | 573 | } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { |
| | 574 | op = .sub; |
| | 575 | llvm_feat = decorated_llvm_feat[1..]; |
| | 576 | } else { |
| | 577 | return error.InvalidLlvmCpuFeaturesFormat; |
| | 578 | } |
| | 579 | for (arch.allFeaturesList()) |feature, index| { |
| | 580 | const this_llvm_name = feature.llvm_name orelse continue; |
| | 581 | if (mem.eql(u8, llvm_feat, this_llvm_name)) { |
| | 582 | switch (op) { |
| | 583 | .add => set.addFeature(@intCast(u8, index)), |
| | 584 | .sub => set.removeFeature(@intCast(u8, index)), |
| | 585 | } |
| | 586 | break; |
| | 587 | } |
| | 588 | } |
| | 589 | } |
| | 590 | return Target.CpuFeatures{ .features = set }; |
| | 591 | } |
| | 592 | |
| 542 | // ABI warning | 593 | // ABI warning |
| 543 | export fn stage2_cmd_targets() c_int { | 594 | export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int { |
| 544 | @import("print_targets.zig").cmdTargets( | 595 | cmdTargets(zig_triple) catch |err| { |
| 545 | std.heap.c_allocator, | | |
| 546 | &[0][]u8{}, | | |
| 547 | &std.io.getStdOut().outStream().stream, | | |
| 548 | ) catch |err| { | | |
| 549 | std.debug.warn("unable to list targets: {}\n", .{@errorName(err)}); | 596 | std.debug.warn("unable to list targets: {}\n", .{@errorName(err)}); |
| 550 | return -1; | 597 | return -1; |
| 551 | }; | 598 | }; |
| 552 | return 0; | 599 | return 0; |
| 553 | } | 600 | } |
| 554 | | 601 | |
| | 602 | fn cmdTargets(zig_triple: [*:0]const u8) !void { |
| | 603 | var target = try Target.parse(mem.toSliceConst(u8, zig_triple)); |
| | 604 | target.Cross.cpu_features = blk: { |
| | 605 | const llvm = @import("llvm.zig"); |
| | 606 | const llvm_cpu_name = llvm.GetHostCPUName(); |
| | 607 | const llvm_cpu_features = llvm.GetNativeFeatures(); |
| | 608 | break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features); |
| | 609 | }; |
| | 610 | return @import("print_targets.zig").cmdTargets( |
| | 611 | std.heap.c_allocator, |
| | 612 | &[0][]u8{}, |
| | 613 | &std.io.getStdOut().outStream().stream, |
| | 614 | target, |
| | 615 | ); |
| | 616 | } |
| | 617 | |
| 555 | const Stage2CpuFeatures = struct { | 618 | const Stage2CpuFeatures = struct { |
| 556 | allocator: *mem.Allocator, | 619 | allocator: *mem.Allocator, |
| 557 | cpu_features: Target.CpuFeatures, | 620 | cpu_features: Target.CpuFeatures, |
| ... | @@ -588,49 +651,17 @@ const Stage2CpuFeatures = struct { | ... | @@ -588,49 +651,17 @@ const Stage2CpuFeatures = struct { |
| 588 | fn createFromLLVM( | 651 | fn createFromLLVM( |
| 589 | allocator: *mem.Allocator, | 652 | allocator: *mem.Allocator, |
| 590 | zig_triple: [*:0]const u8, | 653 | zig_triple: [*:0]const u8, |
| 591 | llvm_cpu_name_z: [*:0]const u8, | 654 | llvm_cpu_name_z: ?[*:0]const u8, |
| 592 | llvm_cpu_features: [*:0]const u8, | 655 | llvm_cpu_features: ?[*:0]const u8, |
| 593 | ) !*Self { | 656 | ) !*Self { |
| 594 | const target = try Target.parse(mem.toSliceConst(u8, zig_triple)); | 657 | const target = try Target.parse(mem.toSliceConst(u8, zig_triple)); |
| 595 | const arch = target.Cross.arch; | 658 | const arch = target.Cross.arch; |
| 596 | const llvm_cpu_name = mem.toSliceConst(u8, llvm_cpu_name_z); | 659 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features); |
| 597 | | 660 | switch (cpu_features) { |
| 598 | for (arch.allCpus()) |cpu| { | 661 | .baseline => return createBaseline(allocator), |
| 599 | const this_llvm_name = cpu.llvm_name orelse continue; | 662 | .cpu => |cpu| return createFromCpu(allocator, arch, cpu), |
| 600 | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { | 663 | .features => |features| return createFromCpuFeatures(allocator, arch, features), |
| 601 | return createFromCpu(allocator, arch, cpu); | | |
| 602 | } | | |
| 603 | } | | |
| 604 | | | |
| 605 | var set = arch.baselineFeatures(); | | |
| 606 | var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ","); | | |
| 607 | while (it.next()) |decorated_llvm_feat| { | | |
| 608 | var op: enum { | | |
| 609 | add, | | |
| 610 | sub, | | |
| 611 | } = undefined; | | |
| 612 | var llvm_feat: []const u8 = undefined; | | |
| 613 | if (mem.startsWith(u8, decorated_llvm_feat, "+")) { | | |
| 614 | op = .add; | | |
| 615 | llvm_feat = decorated_llvm_feat[1..]; | | |
| 616 | } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { | | |
| 617 | op = .sub; | | |
| 618 | llvm_feat = decorated_llvm_feat[1..]; | | |
| 619 | } else { | | |
| 620 | return error.InvalidLlvmCpuFeaturesFormat; | | |
| 621 | } | | |
| 622 | for (arch.allFeaturesList()) |feature, index| { | | |
| 623 | const this_llvm_name = feature.llvm_name orelse continue; | | |
| 624 | if (mem.eql(u8, llvm_feat, this_llvm_name)) { | | |
| 625 | switch (op) { | | |
| 626 | .add => set.addFeature(@intCast(u8, index)), | | |
| 627 | .sub => set.removeFeature(@intCast(u8, index)), | | |
| 628 | } | | |
| 629 | break; | | |
| 630 | } | | |
| 631 | } | | |
| 632 | } | 664 | } |
| 633 | return createFromCpuFeatures(allocator, arch, set); | | |
| 634 | } | 665 | } |
| 635 | | 666 | |
| 636 | fn createFromCpu(allocator: *mem.Allocator, arch: Target.Arch, cpu: *const Target.Cpu) !*Self { | 667 | fn createFromCpu(allocator: *mem.Allocator, arch: Target.Arch, cpu: *const Target.Cpu) !*Self { |
| ... | @@ -823,8 +854,8 @@ export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error { | ... | @@ -823,8 +854,8 @@ export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error { |
| 823 | export fn stage2_cpu_features_llvm( | 854 | export fn stage2_cpu_features_llvm( |
| 824 | result: **Stage2CpuFeatures, | 855 | result: **Stage2CpuFeatures, |
| 825 | zig_triple: [*:0]const u8, | 856 | zig_triple: [*:0]const u8, |
| 826 | llvm_cpu_name: [*:0]const u8, | 857 | llvm_cpu_name: ?[*:0]const u8, |
| 827 | llvm_cpu_features: [*:0]const u8, | 858 | llvm_cpu_features: ?[*:0]const u8, |
| 828 | ) Error { | 859 | ) Error { |
| 829 | result.* = Stage2CpuFeatures.createFromLLVM( | 860 | result.* = Stage2CpuFeatures.createFromLLVM( |
| 830 | std.heap.c_allocator, | 861 | std.heap.c_allocator, |