| ... | @@ -627,7 +627,7 @@ const Stage2CpuFeatures = struct { | ... | @@ -627,7 +627,7 @@ const Stage2CpuFeatures = struct { |
| 627 | | 627 | |
| 628 | const Self = @This(); | 628 | const Self = @This(); |
| 629 | | 629 | |
| 630 | fn createBaseline(allocator: *mem.Allocator) !*Self { | 630 | fn createBaseline(allocator: *mem.Allocator, arch: Target.Arch) !*Self { |
| 631 | const self = try allocator.create(Self); | 631 | const self = try allocator.create(Self); |
| 632 | errdefer allocator.destroy(self); | 632 | errdefer allocator.destroy(self); |
| 633 | | 633 | |
| ... | @@ -641,10 +641,11 @@ const Stage2CpuFeatures = struct { | ... | @@ -641,10 +641,11 @@ const Stage2CpuFeatures = struct { |
| 641 | .allocator = allocator, | 641 | .allocator = allocator, |
| 642 | .cpu_features = .baseline, | 642 | .cpu_features = .baseline, |
| 643 | .llvm_cpu_name = null, | 643 | .llvm_cpu_name = null, |
| 644 | .llvm_features_str = null, | 644 | .llvm_features_str = try initLLVMFeatures(allocator, arch, arch.baselineFeatures()), |
| 645 | .builtin_str = builtin_str, | 645 | .builtin_str = builtin_str, |
| 646 | .cache_hash = cache_hash, | 646 | .cache_hash = cache_hash, |
| 647 | }; | 647 | }; |
| | 648 | |
| 648 | return self; | 649 | return self; |
| 649 | } | 650 | } |
| 650 | | 651 | |
| ... | @@ -658,7 +659,7 @@ const Stage2CpuFeatures = struct { | ... | @@ -658,7 +659,7 @@ const Stage2CpuFeatures = struct { |
| 658 | const arch = target.Cross.arch; | 659 | const arch = target.Cross.arch; |
| 659 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features); | 660 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features); |
| 660 | switch (cpu_features) { | 661 | switch (cpu_features) { |
| 661 | .baseline => return createBaseline(allocator), | 662 | .baseline => return createBaseline(allocator, arch), |
| 662 | .cpu => |cpu| return createFromCpu(allocator, arch, cpu), | 663 | .cpu => |cpu| return createFromCpu(allocator, arch, cpu), |
| 663 | .features => |features| return createFromCpuFeatures(allocator, arch, features), | 664 | .features => |features| return createFromCpuFeatures(allocator, arch, features), |
| 664 | } | 665 | } |
| ... | @@ -688,31 +689,13 @@ const Stage2CpuFeatures = struct { | ... | @@ -688,31 +689,13 @@ const Stage2CpuFeatures = struct { |
| 688 | return self; | 689 | return self; |
| 689 | } | 690 | } |
| 690 | | 691 | |
| 691 | fn createFromCpuFeatures( | 692 | fn initLLVMFeatures( |
| 692 | allocator: *mem.Allocator, | 693 | allocator: *mem.Allocator, |
| 693 | arch: Target.Arch, | 694 | arch: Target.Arch, |
| 694 | feature_set: Target.Cpu.Feature.Set, | 695 | feature_set: Target.Cpu.Feature.Set, |
| 695 | ) !*Self { | 696 | ) ![*:0]const u8 { |
| 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 | | | |
| 713 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | 697 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); |
| 714 | defer llvm_features_buffer.deinit(); | 698 | defer llvm_features_buffer.deinit(); |
| 715 | | | |
| 716 | // First, disable all features. | 699 | // First, disable all features. |
| 717 | // This way, we only get the ones the user requests. | 700 | // This way, we only get the ones the user requests. |
| 718 | const all_features = arch.allFeaturesList(); | 701 | const all_features = arch.allFeaturesList(); |
| ... | @@ -723,7 +706,6 @@ const Stage2CpuFeatures = struct { | ... | @@ -723,7 +706,6 @@ const Stage2CpuFeatures = struct { |
| 723 | try llvm_features_buffer.append(","); | 706 | try llvm_features_buffer.append(","); |
| 724 | } | 707 | } |
| 725 | } | 708 | } |
| 726 | | | |
| 727 | for (all_features) |feature, index| { | 709 | for (all_features) |feature, index| { |
| 728 | if (!feature_set.isEnabled(@intCast(u8, index))) continue; | 710 | if (!feature_set.isEnabled(@intCast(u8, index))) continue; |
| 729 | | 711 | |
| ... | @@ -732,15 +714,43 @@ const Stage2CpuFeatures = struct { | ... | @@ -732,15 +714,43 @@ const Stage2CpuFeatures = struct { |
| 732 | try llvm_features_buffer.append(llvm_name); | 714 | try llvm_features_buffer.append(llvm_name); |
| 733 | try llvm_features_buffer.append(","); | 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 | if (mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")) { | 719 | if (mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")) { |
| 742 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | 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 | try builtin_str_buffer.append( | 755 | try builtin_str_buffer.append( |
| 746 | \\ }), | 756 | \\ }), |
| ... | @@ -752,7 +762,7 @@ const Stage2CpuFeatures = struct { | ... | @@ -752,7 +762,7 @@ const Stage2CpuFeatures = struct { |
| 752 | .allocator = allocator, | 762 | .allocator = allocator, |
| 753 | .cpu_features = .{ .features = feature_set }, | 763 | .cpu_features = .{ .features = feature_set }, |
| 754 | .llvm_cpu_name = null, | 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 | .builtin_str = builtin_str_buffer.toOwnedSlice(), | 766 | .builtin_str = builtin_str_buffer.toOwnedSlice(), |
| 757 | .cache_hash = cache_hash, | 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,13 +853,25 @@ fn parseFeatures(zig_triple: [*:0]const u8, features_text: [*:0]const u8) !*Stag |
| 843 | } | 853 | } |
| 844 | | 854 | |
| 845 | // ABI warning | 855 | // ABI warning |
| 846 | export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error { | 856 | export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures, zig_triple: [*:0]const u8) Error { |
| 847 | result.* = Stage2CpuFeatures.createBaseline(std.heap.c_allocator) catch |err| switch (err) { | 857 | result.* = cpuFeaturesBaseline(zig_triple) catch |err| switch (err) { |
| 848 | error.OutOfMemory => return .OutOfMemory, | 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 | return .None; | 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 | // ABI warning | 875 | // ABI warning |
| 854 | export fn stage2_cpu_features_llvm( | 876 | export fn stage2_cpu_features_llvm( |
| 855 | result: **Stage2CpuFeatures, | 877 | result: **Stage2CpuFeatures, |