| ... | @@ -625,6 +625,63 @@ const Stage2TargetDetails = struct { | ... | @@ -625,6 +625,63 @@ const Stage2TargetDetails = struct { |
| 625 | llvm_features_str: [:0]const u8, | 625 | llvm_features_str: [:0]const u8, |
| 626 | | 626 | |
| 627 | builtin_str: [:0]const u8, | 627 | builtin_str: [:0]const u8, |
| | 628 | |
| | 629 | const Self = @This(); |
| | 630 | |
| | 631 | fn initCpu(allocator: *std.mem.Allocator, arch: @TagType(std.Target.Arch), cpu: *const std.target.Cpu) !Self { |
| | 632 | var builtin_str_buffer = try std.Buffer.init( |
| | 633 | allocator, |
| | 634 | "@import(\"std\").target.TargetDetails{.cpu=&@import(\"std\").target."); |
| | 635 | defer builtin_str_buffer.deinit(); |
| | 636 | |
| | 637 | try builtin_str_buffer.append(@tagName(arch)); |
| | 638 | try builtin_str_buffer.append(".cpu_"); |
| | 639 | try builtin_str_buffer.append(cpu.name); |
| | 640 | try builtin_str_buffer.append("};"); |
| | 641 | return Self{ |
| | 642 | .allocator = allocator, |
| | 643 | .target_details = .{ |
| | 644 | .cpu = cpu, |
| | 645 | }, |
| | 646 | .llvm_cpu_str = cpu.name, |
| | 647 | .llvm_features_str = "", |
| | 648 | .builtin_str = builtin_str_buffer.toOwnedSlice(), |
| | 649 | }; |
| | 650 | } |
| | 651 | |
| | 652 | fn initFeatures(allocator: *std.mem.Allocator, arch: @TagType(std.Target.Arch), features: []*const std.target.Feature) !Self { |
| | 653 | var builtin_str_buffer = try std.Buffer.init( |
| | 654 | allocator, |
| | 655 | "@import(\"std\").target.TargetDetails{.features=&[_]*const @import(\"std\").target.Feature{\n"); |
| | 656 | defer builtin_str_buffer.deinit(); |
| | 657 | |
| | 658 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); |
| | 659 | defer llvm_features_buffer.deinit(); |
| | 660 | |
| | 661 | for (features) |feature| { |
| | 662 | try llvm_features_buffer.append("+"); |
| | 663 | try llvm_features_buffer.append(feature.llvm_name); |
| | 664 | try llvm_features_buffer.append(","); |
| | 665 | |
| | 666 | try builtin_str_buffer.append("&@import(\"std\").target."); |
| | 667 | try builtin_str_buffer.append(@tagName(arch)); |
| | 668 | try builtin_str_buffer.append(".feature_"); |
| | 669 | try builtin_str_buffer.append(feature.name); |
| | 670 | try builtin_str_buffer.append(","); |
| | 671 | } |
| | 672 | |
| | 673 | try builtin_str_buffer.append("}};"); |
| | 674 | |
| | 675 | return Self{ |
| | 676 | .allocator = allocator, |
| | 677 | .target_details = std.target.TargetDetails{ |
| | 678 | .features = features, |
| | 679 | }, |
| | 680 | .llvm_cpu_str = "", |
| | 681 | .llvm_features_str = llvm_features_buffer.toOwnedSlice(), |
| | 682 | .builtin_str = builtin_str_buffer.toOwnedSlice(), |
| | 683 | }; |
| | 684 | } |
| 628 | }; | 685 | }; |
| 629 | | 686 | |
| 630 | // ABI warning | 687 | // ABI warning |
| ... | @@ -658,32 +715,14 @@ export fn stage2_target_details_parse_features(arch_str: ?[*:0]const u8, feature | ... | @@ -658,32 +715,14 @@ export fn stage2_target_details_parse_features(arch_str: ?[*:0]const u8, feature |
| 658 | } | 715 | } |
| 659 | | 716 | |
| 660 | fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { | 717 | fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { |
| | 718 | const allocator = std.heap.c_allocator; |
| | 719 | |
| 661 | const cpus = std.target.getCpusForArch(arch); | 720 | const cpus = std.target.getCpusForArch(arch); |
| 662 | | 721 | |
| 663 | for (cpus) |cpu| { | 722 | for (cpus) |cpu| { |
| 664 | if (std.mem.eql(u8, str, cpu.name)) { | 723 | if (std.mem.eql(u8, str, cpu.name)) { |
| 665 | const allocator = std.heap.c_allocator; | | |
| 666 | | | |
| 667 | var builtin_str_buffer = try std.Buffer.init( | | |
| 668 | allocator, | | |
| 669 | "@import(\"std\").target.TargetDetails{.cpu=&@import(\"std\").target."); | | |
| 670 | defer builtin_str_buffer.deinit(); | | |
| 671 | | | |
| 672 | try builtin_str_buffer.append(@tagName(arch)); | | |
| 673 | try builtin_str_buffer.append(".cpu_"); | | |
| 674 | try builtin_str_buffer.append(cpu.name); | | |
| 675 | try builtin_str_buffer.append("};"); | | |
| 676 | | | |
| 677 | const ptr = try allocator.create(Stage2TargetDetails); | 724 | const ptr = try allocator.create(Stage2TargetDetails); |
| 678 | ptr.* = .{ | 725 | ptr.* = try Stage2TargetDetails.initCpu(std.heap.c_allocator, arch, cpu); |
| 679 | .allocator = allocator, | | |
| 680 | .target_details = .{ | | |
| 681 | .cpu = cpu, | | |
| 682 | }, | | |
| 683 | .llvm_cpu_str = cpu.name, | | |
| 684 | .llvm_features_str = "", | | |
| 685 | .builtin_str = builtin_str_buffer.toOwnedSlice(), | | |
| 686 | }; | | |
| 687 | | 726 | |
| 688 | return ptr; | 727 | return ptr; |
| 689 | } | 728 | } |
| ... | @@ -700,11 +739,6 @@ fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2Targe | ... | @@ -700,11 +739,6 @@ fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2Targe |
| 700 | var features = std.ArrayList(*const std.target.Feature).init(allocator); | 739 | var features = std.ArrayList(*const std.target.Feature).init(allocator); |
| 701 | defer features.deinit(); | 740 | defer features.deinit(); |
| 702 | | 741 | |
| 703 | var builtin_str_buffer = try std.Buffer.init( | | |
| 704 | allocator, | | |
| 705 | "@import(\"std\").target.TargetDetails{.features=&[_]*const @import(\"std\").target.Feature{\n"); | | |
| 706 | defer builtin_str_buffer.deinit(); | | |
| 707 | | | |
| 708 | var start: usize = 0; | 742 | var start: usize = 0; |
| 709 | while (start < str.len) { | 743 | while (start < str.len) { |
| 710 | const next_comma_pos = std.mem.indexOfScalar(u8, str[start..], ',') orelse str.len - start; | 744 | const next_comma_pos = std.mem.indexOfScalar(u8, str[start..], ',') orelse str.len - start; |
| ... | @@ -725,39 +759,15 @@ fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2Targe | ... | @@ -725,39 +759,15 @@ fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2Targe |
| 725 | if (feature) |f| { | 759 | if (feature) |f| { |
| 726 | features.append(f) catch @panic("out of memory"); | 760 | features.append(f) catch @panic("out of memory"); |
| 727 | | 761 | |
| 728 | try builtin_str_buffer.append("&@import(\"std\").target."); | | |
| 729 | try builtin_str_buffer.append(@tagName(arch)); | | |
| 730 | try builtin_str_buffer.append(".feature_"); | | |
| 731 | try builtin_str_buffer.append(f.name); | | |
| 732 | try builtin_str_buffer.append(","); | | |
| 733 | } else { | 762 | } else { |
| 734 | return error.InvalidFeature; | 763 | return error.InvalidFeature; |
| 735 | } | 764 | } |
| 736 | } | 765 | } |
| 737 | | 766 | |
| 738 | try builtin_str_buffer.append("}};"); | | |
| 739 | | | |
| 740 | const features_slice = features.toOwnedSlice(); | 767 | const features_slice = features.toOwnedSlice(); |
| 741 | | 768 | |
| 742 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | | |
| 743 | defer llvm_features_buffer.deinit(); | | |
| 744 | | | |
| 745 | for (features_slice) |feature| { | | |
| 746 | try llvm_features_buffer.append("+"); | | |
| 747 | try llvm_features_buffer.append(feature.llvm_name); | | |
| 748 | try llvm_features_buffer.append(","); | | |
| 749 | } | | |
| 750 | | | |
| 751 | const ptr = try allocator.create(Stage2TargetDetails); | 769 | const ptr = try allocator.create(Stage2TargetDetails); |
| 752 | ptr.* = Stage2TargetDetails{ | 770 | ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, features_slice); |
| 753 | .allocator = allocator, | | |
| 754 | .target_details = std.target.TargetDetails{ | | |
| 755 | .features = features_slice, | | |
| 756 | }, | | |
| 757 | .llvm_cpu_str = "", | | |
| 758 | .llvm_features_str = llvm_features_buffer.toOwnedSlice(), | | |
| 759 | .builtin_str = builtin_str_buffer.toOwnedSlice(), | | |
| 760 | }; | | |
| 761 | | 771 | |
| 762 | return ptr; | 772 | return ptr; |
| 763 | } | 773 | } |
| ... | @@ -800,3 +810,68 @@ export fn stage2_target_details_get_builtin_str(target_details: ?*const Stage2Ta | ... | @@ -800,3 +810,68 @@ export fn stage2_target_details_get_builtin_str(target_details: ?*const Stage2Ta |
| 800 | | 810 | |
| 801 | return @as([*:0]const u8, ""); | 811 | return @as([*:0]const u8, ""); |
| 802 | } | 812 | } |
| | 813 | |
| | 814 | const riscv_default_features: []*const std.target.Feature = &[_]*const std.target.Feature { |
| | 815 | &std.target.riscv.feature_a, |
| | 816 | &std.target.riscv.feature_c, |
| | 817 | &std.target.riscv.feature_d, |
| | 818 | &std.target.riscv.feature_f, |
| | 819 | &std.target.riscv.feature_m, |
| | 820 | &std.target.riscv.feature_relax, |
| | 821 | }; |
| | 822 | |
| | 823 | const i386_default_features: []*const std.target.Feature = &[_]*const std.target.Feature { |
| | 824 | &std.target.x86.feature_cmov, |
| | 825 | &std.target.x86.feature_cx8, |
| | 826 | &std.target.x86.feature_fxsr, |
| | 827 | &std.target.x86.feature_mmx, |
| | 828 | &std.target.x86.feature_nopl, |
| | 829 | &std.target.x86.feature_sse, |
| | 830 | &std.target.x86.feature_sse2, |
| | 831 | &std.target.x86.feature_slowUnalignedMem16, |
| | 832 | &std.target.x86.feature_x87, |
| | 833 | }; |
| | 834 | |
| | 835 | // Same as above but without sse. |
| | 836 | const i386_default_features_freestanding: []*const std.target.Feature = &[_]*const std.target.Feature { |
| | 837 | &std.target.x86.feature_cmov, |
| | 838 | &std.target.x86.feature_cx8, |
| | 839 | &std.target.x86.feature_fxsr, |
| | 840 | &std.target.x86.feature_mmx, |
| | 841 | &std.target.x86.feature_nopl, |
| | 842 | &std.target.x86.feature_slowUnalignedMem16, |
| | 843 | &std.target.x86.feature_x87, |
| | 844 | }; |
| | 845 | |
| | 846 | // ABI warning |
| | 847 | export fn stage2_target_details_get_default(arch_str: ?[*:0]const u8, os_str: ?[*:0]const u8) ?*Stage2TargetDetails { |
| | 848 | if (arch_str == null) return null; |
| | 849 | if (os_str == null) return null; |
| | 850 | |
| | 851 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch return null; |
| | 852 | const os = Target.parseOs(std.mem.toSliceConst(u8, os_str.?)) catch return null; |
| | 853 | |
| | 854 | return createDefaultTargetDetails(arch, os) catch return null; |
| | 855 | } |
| | 856 | |
| | 857 | fn createDefaultTargetDetails(arch: @TagType(std.Target.Arch), os: std.Target.Os) !?*Stage2TargetDetails { |
| | 858 | const allocator = std.heap.c_allocator; |
| | 859 | |
| | 860 | return switch (arch) { |
| | 861 | .riscv32, .riscv64 => blk: { |
| | 862 | const ptr = try allocator.create(Stage2TargetDetails); |
| | 863 | ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, riscv_default_features); |
| | 864 | break :blk ptr; |
| | 865 | }, |
| | 866 | .i386 => blk: { |
| | 867 | const ptr = try allocator.create(Stage2TargetDetails); |
| | 868 | const features = switch (os) { |
| | 869 | .freestanding => i386_default_features_freestanding, |
| | 870 | else => i386_default_features, |
| | 871 | }; |
| | 872 | ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, features); |
| | 873 | break :blk ptr; |
| | 874 | }, |
| | 875 | else => null, |
| | 876 | }; |
| | 877 | } |