| ... | ... | @@ -627,7 +627,7 @@ const Stage2CpuFeatures = struct { |
| 627 | 627 | |
| 628 | 628 | const Self = @This(); |
| 629 | 629 | |
| 630 | | fn createBaseline(allocator: *mem.Allocator) !*Self { |
| 630 | fn createBaseline(allocator: *mem.Allocator, arch: Target.Arch) !*Self { |
| 631 | 631 | const self = try allocator.create(Self); |
| 632 | 632 | errdefer allocator.destroy(self); |
| 633 | 633 | |
| ... | ... | @@ -641,10 +641,11 @@ const Stage2CpuFeatures = struct { |
| 641 | 641 | .allocator = allocator, |
| 642 | 642 | .cpu_features = .baseline, |
| 643 | 643 | .llvm_cpu_name = null, |
| 644 | | .llvm_features_str = null, |
| 644 | .llvm_features_str = try initLLVMFeatures(allocator, arch, arch.baselineFeatures()), |
| 645 | 645 | .builtin_str = builtin_str, |
| 646 | 646 | .cache_hash = cache_hash, |
| 647 | 647 | }; |
| 648 | |
| 648 | 649 | return self; |
| 649 | 650 | } |
| 650 | 651 | |
| ... | ... | @@ -658,7 +659,7 @@ const Stage2CpuFeatures = struct { |
| 658 | 659 | const arch = target.Cross.arch; |
| 659 | 660 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features); |
| 660 | 661 | switch (cpu_features) { |
| 661 | | .baseline => return createBaseline(allocator), |
| 662 | .baseline => return createBaseline(allocator, arch), |
| 662 | 663 | .cpu => |cpu| return createFromCpu(allocator, arch, cpu), |
| 663 | 664 | .features => |features| return createFromCpuFeatures(allocator, arch, features), |
| 664 | 665 | } |
| ... | ... | @@ -688,31 +689,13 @@ const Stage2CpuFeatures = struct { |
| 688 | 689 | return self; |
| 689 | 690 | } |
| 690 | 691 | |
| 691 | | fn createFromCpuFeatures( |
| 692 | fn initLLVMFeatures( |
| 692 | 693 | allocator: *mem.Allocator, |
| 693 | 694 | arch: Target.Arch, |
| 694 | 695 | feature_set: Target.Cpu.Feature.Set, |
| 695 | | ) !*Self { |
| 696 | | const self = try allocator.create(Self); |
| 697 | | errdefer allocator.destroy(self); |
| 698 | | |
| 699 | | const cache_hash = try std.fmt.allocPrint0(allocator, "\n{x}", .{feature_set}); |
| 700 | | errdefer allocator.free(cache_hash); |
| 701 | | |
| 702 | | const generic_arch_name = arch.genericName(); |
| 703 | | var builtin_str_buffer = try std.Buffer.allocPrint( |
| 704 | | allocator, |
| 705 | | \\CpuFeatures{{ |
| 706 | | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ |
| 707 | | \\ |
| 708 | | , |
| 709 | | .{ generic_arch_name, generic_arch_name }, |
| 710 | | ); |
| 711 | | defer builtin_str_buffer.deinit(); |
| 712 | | |
| 696 | ) ![*:0]const u8 { |
| 713 | 697 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); |
| 714 | 698 | defer llvm_features_buffer.deinit(); |
| 715 | | |
| 716 | 699 | // First, disable all features. |
| 717 | 700 | // This way, we only get the ones the user requests. |
| 718 | 701 | const all_features = arch.allFeaturesList(); |
| ... | ... | @@ -723,7 +706,6 @@ const Stage2CpuFeatures = struct { |
| 723 | 706 | try llvm_features_buffer.append(","); |
| 724 | 707 | } |
| 725 | 708 | } |
| 726 | | |
| 727 | 709 | for (all_features) |feature, index| { |
| 728 | 710 | if (!feature_set.isEnabled(@intCast(u8, index))) continue; |
| 729 | 711 | |
| ... | ... | @@ -732,15 +714,43 @@ const Stage2CpuFeatures = struct { |
| 732 | 714 | try llvm_features_buffer.append(llvm_name); |
| 733 | 715 | try llvm_features_buffer.append(","); |
| 734 | 716 | } |
| 735 | | |
| 736 | | try builtin_str_buffer.append(" ."); |
| 737 | | try builtin_str_buffer.append(feature.name); |
| 738 | | try builtin_str_buffer.append(",\n"); |
| 739 | 717 | } |
| 740 | 718 | |
| 741 | 719 | if (mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")) { |
| 742 | 720 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); |
| 743 | 721 | } |
| 722 | return llvm_features_buffer.toOwnedSlice().ptr; |
| 723 | } |
| 724 | |
| 725 | fn createFromCpuFeatures( |
| 726 | allocator: *mem.Allocator, |
| 727 | arch: Target.Arch, |
| 728 | feature_set: Target.Cpu.Feature.Set, |
| 729 | ) !*Self { |
| 730 | const self = try allocator.create(Self); |
| 731 | errdefer allocator.destroy(self); |
| 732 | |
| 733 | const cache_hash = try std.fmt.allocPrint0(allocator, "\n{x}", .{feature_set}); |
| 734 | errdefer allocator.free(cache_hash); |
| 735 | |
| 736 | const generic_arch_name = arch.genericName(); |
| 737 | var builtin_str_buffer = try std.Buffer.allocPrint( |
| 738 | allocator, |
| 739 | \\CpuFeatures{{ |
| 740 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ |
| 741 | \\ |
| 742 | , |
| 743 | .{ generic_arch_name, generic_arch_name }, |
| 744 | ); |
| 745 | defer builtin_str_buffer.deinit(); |
| 746 | |
| 747 | for (arch.allFeaturesList()) |feature, index| { |
| 748 | if (!feature_set.isEnabled(@intCast(u8, index))) continue; |
| 749 | |
| 750 | try builtin_str_buffer.append(" ."); |
| 751 | try builtin_str_buffer.append(feature.name); |
| 752 | try builtin_str_buffer.append(",\n"); |
| 753 | } |
| 744 | 754 | |
| 745 | 755 | try builtin_str_buffer.append( |
| 746 | 756 | \\ }), |
| ... | ... | @@ -752,7 +762,7 @@ const Stage2CpuFeatures = struct { |
| 752 | 762 | .allocator = allocator, |
| 753 | 763 | .cpu_features = .{ .features = feature_set }, |
| 754 | 764 | .llvm_cpu_name = null, |
| 755 | | .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr, |
| 765 | .llvm_features_str = try initLLVMFeatures(allocator, arch, feature_set), |
| 756 | 766 | .builtin_str = builtin_str_buffer.toOwnedSlice(), |
| 757 | 767 | .cache_hash = cache_hash, |
| 758 | 768 | }; |
| ... | ... | @@ -843,13 +853,25 @@ fn parseFeatures(zig_triple: [*:0]const u8, features_text: [*:0]const u8) !*Stag |
| 843 | 853 | } |
| 844 | 854 | |
| 845 | 855 | // ABI warning |
| 846 | | export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error { |
| 847 | | result.* = Stage2CpuFeatures.createBaseline(std.heap.c_allocator) catch |err| switch (err) { |
| 856 | export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures, zig_triple: [*:0]const u8) Error { |
| 857 | result.* = cpuFeaturesBaseline(zig_triple) catch |err| switch (err) { |
| 848 | 858 | error.OutOfMemory => return .OutOfMemory, |
| 859 | error.UnknownArchitecture => return .UnknownArchitecture, |
| 860 | error.UnknownSubArchitecture => return .UnknownSubArchitecture, |
| 861 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, |
| 862 | error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, |
| 863 | error.MissingOperatingSystem => return .MissingOperatingSystem, |
| 864 | error.MissingArchitecture => return .MissingArchitecture, |
| 849 | 865 | }; |
| 850 | 866 | return .None; |
| 851 | 867 | } |
| 852 | 868 | |
| 869 | fn cpuFeaturesBaseline(zig_triple: [*:0]const u8) !*Stage2CpuFeatures { |
| 870 | const target = try Target.parse(mem.toSliceConst(u8, zig_triple)); |
| 871 | const arch = target.Cross.arch; |
| 872 | return Stage2CpuFeatures.createBaseline(std.heap.c_allocator, arch); |
| 873 | } |
| 874 | |
| 853 | 875 | // ABI warning |
| 854 | 876 | export fn stage2_cpu_features_llvm( |
| 855 | 877 | result: **Stage2CpuFeatures, |