| ... | ... | @@ -625,6 +625,63 @@ const Stage2TargetDetails = struct { |
| 625 | 625 | llvm_features_str: [:0]const u8, |
| 626 | 626 | |
| 627 | 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 | 687 | // ABI warning |
| ... | ... | @@ -658,32 +715,14 @@ export fn stage2_target_details_parse_features(arch_str: ?[*:0]const u8, feature |
| 658 | 715 | } |
| 659 | 716 | |
| 660 | 717 | fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { |
| 718 | const allocator = std.heap.c_allocator; |
| 719 | |
| 661 | 720 | const cpus = std.target.getCpusForArch(arch); |
| 662 | 721 | |
| 663 | 722 | for (cpus) |cpu| { |
| 664 | 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 | 724 | const ptr = try allocator.create(Stage2TargetDetails); |
| 678 | | ptr.* = .{ |
| 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 | | }; |
| 725 | ptr.* = try Stage2TargetDetails.initCpu(std.heap.c_allocator, arch, cpu); |
| 687 | 726 | |
| 688 | 727 | return ptr; |
| 689 | 728 | } |
| ... | ... | @@ -700,11 +739,6 @@ fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2Targe |
| 700 | 739 | var features = std.ArrayList(*const std.target.Feature).init(allocator); |
| 701 | 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 | 742 | var start: usize = 0; |
| 709 | 743 | while (start < str.len) { |
| 710 | 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 | 759 | if (feature) |f| { |
| 726 | 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 | 762 | } else { |
| 734 | 763 | return error.InvalidFeature; |
| 735 | 764 | } |
| 736 | 765 | } |
| 737 | 766 | |
| 738 | | try builtin_str_buffer.append("}};"); |
| 739 | | |
| 740 | 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 | 769 | const ptr = try allocator.create(Stage2TargetDetails); |
| 752 | | ptr.* = Stage2TargetDetails{ |
| 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 | | }; |
| 770 | ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, features_slice); |
| 761 | 771 | |
| 762 | 772 | return ptr; |
| 763 | 773 | } |
| ... | ... | @@ -800,3 +810,68 @@ export fn stage2_target_details_get_builtin_str(target_details: ?*const Stage2Ta |
| 800 | 810 | |
| 801 | 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 | } |