| author | |
| committer | |
| log | c61856ebcf54a55f1c17a5fd6a3b3300115b2c65 |
| tree | 16c00869a16f4c80f697be2822bbfa80c1b04cef |
| parent | 79a2747de490ca2bb1603fd1ce55637fb5278671 |
| signature | Commit is signed but in an unrecognized format. |
8 files changed, 223 insertions(+), 124 deletions(-)
lib/std/build.zig+17-25| ... | @@ -1199,8 +1199,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1199,8 +1199,7 @@ pub const LibExeObjStep = struct { |
| 1199 | 1199 | ||
| 1200 | subsystem: ?builtin.SubSystem = null, | 1200 | subsystem: ?builtin.SubSystem = null, |
| 1201 | 1201 | ||
| 1202 | cpu: ?[]const u8 = null, | 1202 | target_details: ?std.target.TargetDetails = null, |
| 1203 | features: ?[]const u8 = null, | ||
| 1204 | 1203 | ||
| 1205 | const LinkObject = union(enum) { | 1204 | const LinkObject = union(enum) { |
| 1206 | StaticPath: []const u8, | 1205 | StaticPath: []const u8, |
| ... | @@ -1387,21 +1386,8 @@ pub const LibExeObjStep = struct { | ... | @@ -1387,21 +1386,8 @@ pub const LibExeObjStep = struct { |
| 1387 | self.computeOutFileNames(); | 1386 | self.computeOutFileNames(); |
| 1388 | } | 1387 | } |
| 1389 | 1388 | ||
| 1390 | pub fn setCpu(self: *LibExeObjStep, cpu: *const std.target.Cpu) void { | 1389 | pub fn setTargetDetails(self: *LibExeObjStep, target_details: std.target.TargetDetails) void { |
| 1391 | self.cpu = cpu.name; | 1390 | self.target_details = target_details; |
| 1392 | } | ||
| 1393 | |||
| 1394 | pub fn setFeatures(self: *LibExeObjStep, features: []*const std.target.Feature) void { | ||
| 1395 | var features_str_buffer = std.Buffer.init(self.builder.allocator, "") catch unreachable; | ||
| 1396 | defer features_str_buffer.deinit(); | ||
| 1397 | |||
| 1398 | for (features) |feature| { | ||
| 1399 | features_str_buffer.append("+") catch unreachable; | ||
| 1400 | features_str_buffer.append(feature.name) catch unreachable; | ||
| 1401 | features_str_buffer.append(",") catch unreachable; | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | self.features = features_str_buffer.toOwnedSlice(); | ||
| 1405 | } | 1391 | } |
| 1406 | 1392 | ||
| 1407 | pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void { | 1393 | pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void { |
| ... | @@ -1994,14 +1980,20 @@ pub const LibExeObjStep = struct { | ... | @@ -1994,14 +1980,20 @@ pub const LibExeObjStep = struct { |
| 1994 | }, | 1980 | }, |
| 1995 | } | 1981 | } |
| 1996 | 1982 | ||
| 1997 | if (self.cpu) |cpu| { | 1983 | if (self.target_details) |td| { |
| 1998 | try zig_args.append("--cpu"); | 1984 | switch (td) { |
| 1999 | try zig_args.append(cpu); | 1985 | .cpu => |cpu| { |
| 2000 | } | 1986 | try zig_args.append("--cpu"); |
| 2001 | 1987 | try zig_args.append(cpu.name); | |
| 2002 | if (self.features) |features| { | 1988 | }, |
| 2003 | try zig_args.append("--features"); | 1989 | .features => |features| { |
| 2004 | try zig_args.append(features); | 1990 | try zig_args.append("--features"); |
| 1991 | for (features) |feature| { | ||
| 1992 | try zig_args.append(feature.name); | ||
| 1993 | try zig_args.append(","); | ||
| 1994 | } | ||
| 1995 | }, | ||
| 1996 | } | ||
| 2005 | } | 1997 | } |
| 2006 | 1998 | ||
| 2007 | if (self.target_glibc) |ver| { | 1999 | if (self.target_glibc) |ver| { |
lib/std/target.zig+6| ... | @@ -860,6 +860,7 @@ pub const x86 = @import("target/x86.zig"); | ... | @@ -860,6 +860,7 @@ pub const x86 = @import("target/x86.zig"); |
| 860 | 860 | ||
| 861 | pub const Feature = struct { | 861 | pub const Feature = struct { |
| 862 | name: []const u8, | 862 | name: []const u8, |
| 863 | llvm_name: []const u8, | ||
| 863 | description: []const u8, | 864 | description: []const u8, |
| 864 | 865 | ||
| 865 | dependencies: []*const Feature, | 866 | dependencies: []*const Feature, |
| ... | @@ -872,6 +873,11 @@ pub const Cpu = struct { | ... | @@ -872,6 +873,11 @@ pub const Cpu = struct { |
| 872 | dependencies: []*const Feature, | 873 | dependencies: []*const Feature, |
| 873 | }; | 874 | }; |
| 874 | 875 | ||
| 876 | pub const TargetDetails = union(enum) { | ||
| 877 | cpu: *const Cpu, | ||
| 878 | features: []*const Feature, | ||
| 879 | }; | ||
| 880 | |||
| 875 | pub fn getFeaturesForArch(arch: @TagType(Target.Arch)) []*const Feature { | 881 | pub fn getFeaturesForArch(arch: @TagType(Target.Arch)) []*const Feature { |
| 876 | return switch (arch) { | 882 | return switch (arch) { |
| 877 | .arm, .armeb, .thumb, .thumbeb => arm.features, | 883 | .arm, .armeb, .thumb, .thumbeb => arm.features, |
src-self-hosted/stage1.zig+137-78| ... | @@ -530,13 +530,13 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz | ... | @@ -530,13 +530,13 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz |
| 530 | } | 530 | } |
| 531 | 531 | ||
| 532 | // ABI warning | 532 | // ABI warning |
| 533 | export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void { | 533 | export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_dependencies: bool) void { |
| 534 | printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| { | 534 | printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_dependencies) catch |err| { |
| 535 | std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) }); | 535 | std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) }); |
| 536 | }; | 536 | }; |
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void { | 539 | fn printFeaturesForArch(arch_name: []const u8, show_dependencies: bool) !void { |
| 540 | const stdout_stream = &std.io.getStdOut().outStream().stream; | 540 | const stdout_stream = &std.io.getStdOut().outStream().stream; |
| 541 | 541 | ||
| 542 | const arch = Target.parseArchTag(arch_name) catch { | 542 | const arch = Target.parseArchTag(arch_name) catch { |
| ... | @@ -565,22 +565,22 @@ fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void { | ... | @@ -565,22 +565,22 @@ fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void { |
| 565 | 565 | ||
| 566 | try stdout_stream.print(" - {}\n", .{ feature.description }); | 566 | try stdout_stream.print(" - {}\n", .{ feature.description }); |
| 567 | 567 | ||
| 568 | if (show_subfeatures and feature.subfeatures.len > 0) { | 568 | if (show_dependencies and feature.dependencies.len > 0) { |
| 569 | for (feature.subfeatures) |subfeature| { | 569 | for (feature.dependencies) |dependency| { |
| 570 | try stdout_stream.print(" {}\n", .{ subfeature.name }); | 570 | try stdout_stream.print(" {}\n", .{ dependency.name }); |
| 571 | } | 571 | } |
| 572 | } | 572 | } |
| 573 | } | 573 | } |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | // ABI warning | 576 | // ABI warning |
| 577 | export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void { | 577 | export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_dependencies: bool) void { |
| 578 | printCpusForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| { | 578 | printCpusForArch(arch_name_ptr[0..arch_name_len], show_dependencies) catch |err| { |
| 579 | std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) }); | 579 | std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) }); |
| 580 | }; | 580 | }; |
| 581 | } | 581 | } |
| 582 | 582 | ||
| 583 | fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void { | 583 | fn printCpusForArch(arch_name: []const u8, show_dependencies: bool) !void { |
| 584 | const stdout_stream = &std.io.getStdOut().outStream().stream; | 584 | const stdout_stream = &std.io.getStdOut().outStream().stream; |
| 585 | 585 | ||
| 586 | const arch = Target.parseArchTag(arch_name) catch { | 586 | const arch = Target.parseArchTag(arch_name) catch { |
| ... | @@ -609,99 +609,158 @@ fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void { | ... | @@ -609,99 +609,158 @@ fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void { |
| 609 | 609 | ||
| 610 | try stdout_stream.write("\n"); | 610 | try stdout_stream.write("\n"); |
| 611 | 611 | ||
| 612 | if (show_subfeatures and cpu.subfeatures.len > 0) { | 612 | if (show_dependencies and cpu.dependencies.len > 0) { |
| 613 | for (cpu.subfeatures) |subfeature| { | 613 | for (cpu.dependencies) |dependency| { |
| 614 | try stdout_stream.print(" {}\n", .{ subfeature.name }); | 614 | try stdout_stream.print(" {}\n", .{ dependency.name }); |
| 615 | } | 615 | } |
| 616 | } | 616 | } |
| 617 | } | 617 | } |
| 618 | } | 618 | } |
| 619 | 619 | ||
| 620 | // use target_arch_name(ZigLLVM_ArchType) to get name from main.cpp 'target'. | 620 | const Stage2TargetDetails = struct { |
| 621 | allocator: *std.mem.Allocator, | ||
| 622 | target_details: std.target.TargetDetails, | ||
| 623 | |||
| 624 | llvm_cpu_str: [:0]const u8, | ||
| 625 | llvm_features_str: [:0]const u8, | ||
| 626 | }; | ||
| 627 | |||
| 621 | // ABI warning | 628 | // ABI warning |
| 622 | export fn stage2_validate_cpu_and_features( | 629 | export fn stage2_target_details_parse_cpu(arch_str: ?[*:0]const u8, cpu_str: ?[*:0]const u8) ?*Stage2TargetDetails { |
| 623 | arch_name: [*:0]const u8, | 630 | if (cpu_str == null) return null; |
| 624 | cpu: ?[*:0]const u8, | 631 | if (arch_str == null) return null; |
| 625 | features: ?[*:0]const u8, | 632 | |
| 626 | ) bool { | 633 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch { |
| 627 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_name)) catch { | 634 | return null; |
| 628 | std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{ arch_name }); | 635 | }; |
| 629 | return false; | 636 | return parseCpu(arch, std.mem.toSliceConst(u8, cpu_str.?)) catch |err| { |
| 637 | switch (err) { | ||
| 638 | error.OutOfMemory => @panic("out of memory"), | ||
| 639 | else => return null, | ||
| 640 | } | ||
| 641 | }; | ||
| 642 | } | ||
| 643 | |||
| 644 | // ABI warning | ||
| 645 | export fn stage2_target_details_parse_features(arch_str: ?[*:0]const u8, features_str: ?[*:0]const u8) ?*Stage2TargetDetails { | ||
| 646 | if (features_str == null) return null; | ||
| 647 | if (arch_str == null) return null; | ||
| 648 | |||
| 649 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch return null; | ||
| 650 | return parseFeatures(arch, std.mem.toSliceConst(u8, features_str.?)) catch |err| { | ||
| 651 | switch (err) { | ||
| 652 | error.OutOfMemory => @panic("out of memory"), | ||
| 653 | else => return null, | ||
| 654 | } | ||
| 630 | }; | 655 | }; |
| 656 | } | ||
| 631 | 657 | ||
| 632 | const res = validateCpuAndFeatures( | 658 | fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { |
| 633 | arch, | 659 | const cpus = std.target.getCpusForArch(arch); |
| 634 | if (cpu) |def_cpu| std.mem.toSliceConst(u8, def_cpu) else "", | ||
| 635 | if (features) |def_features| std.mem.toSliceConst(u8, def_features) else ""); | ||
| 636 | 660 | ||
| 637 | switch (res) { | 661 | for (cpus) |cpu| { |
| 638 | .Ok => return true, | 662 | if (std.mem.eql(u8, str, cpu.name)) { |
| 639 | .InvalidCpu => |invalid_cpu| { | 663 | const allocator = std.heap.c_allocator; |
| 640 | std.debug.warn("Invalid CPU '{}'\n", .{ invalid_cpu }); | 664 | |
| 641 | return false; | 665 | const ptr = try allocator.create(Stage2TargetDetails); |
| 642 | }, | 666 | ptr.* = .{ |
| 643 | .InvalidFeaturesString => { | 667 | .allocator = allocator, |
| 644 | std.debug.warn("Invalid features string\n", .{}); | 668 | .target_details = .{ |
| 645 | std.debug.warn("Must have format \"+yes_feature,-no_feature\"\n", .{}); | 669 | .cpu = cpu, |
| 646 | return false; | 670 | }, |
| 647 | }, | 671 | .llvm_cpu_str = cpu.name, |
| 648 | .InvalidFeature => |invalid_feature| { | 672 | .llvm_features_str = "", |
| 649 | std.debug.warn("Invalid feature '{}'\n", .{ invalid_feature }); | 673 | }; |
| 650 | return false; | 674 | |
| 675 | return ptr; | ||
| 651 | } | 676 | } |
| 652 | } | 677 | } |
| 653 | } | ||
| 654 | 678 | ||
| 655 | const ValidateCpuAndFeaturesResult = union(enum) { | 679 | return error.InvalidCpu; |
| 656 | Ok, | 680 | } |
| 657 | InvalidCpu: []const u8, | ||
| 658 | InvalidFeaturesString, | ||
| 659 | InvalidFeature: []const u8, | ||
| 660 | }; | ||
| 661 | 681 | ||
| 662 | fn validateCpuAndFeatures(arch: @TagType(std.Target.Arch), cpu: []const u8, features: []const u8) ValidateCpuAndFeaturesResult { | 682 | fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { |
| 683 | const allocator = std.heap.c_allocator; | ||
| 663 | 684 | ||
| 664 | const known_cpus = std.target.getCpusForArch(arch); | ||
| 665 | const known_features = std.target.getFeaturesForArch(arch); | 685 | const known_features = std.target.getFeaturesForArch(arch); |
| 666 | 686 | ||
| 667 | if (cpu.len > 0) { | 687 | var features = std.ArrayList(*const std.target.Feature).init(allocator); |
| 668 | var found_cpu = false; | 688 | defer features.deinit(); |
| 669 | for (known_cpus) |known_cpu| { | 689 | |
| 670 | if (std.mem.eql(u8, cpu, known_cpu.name)) { | 690 | var start: usize = 0; |
| 671 | found_cpu = true; | 691 | while (start < str.len) { |
| 692 | const next_comma_pos = std.mem.indexOfScalar(u8, str[start..], ',') orelse str.len - start; | ||
| 693 | const feature_str = std.mem.trim(u8, str[start..start+next_comma_pos], " "); | ||
| 694 | |||
| 695 | start += next_comma_pos + 1; | ||
| 696 | |||
| 697 | if (feature_str.len == 0) continue; | ||
| 698 | |||
| 699 | var feature: ?*const std.target.Feature = null; | ||
| 700 | for (known_features) |known_feature| { | ||
| 701 | if (std.mem.eql(u8, feature_str, known_feature.name)) { | ||
| 702 | feature = known_feature; | ||
| 672 | break; | 703 | break; |
| 673 | } | 704 | } |
| 674 | } | 705 | } |
| 675 | 706 | ||
| 676 | if (!found_cpu) { | 707 | if (feature) |f| { |
| 677 | return .{ .InvalidCpu = cpu }; | 708 | features.append(f) catch @panic("out of memory"); |
| 709 | } else { | ||
| 710 | return error.InvalidFeature; | ||
| 678 | } | 711 | } |
| 679 | } | 712 | } |
| 713 | |||
| 714 | const features_slice = features.toOwnedSlice(); | ||
| 680 | 715 | ||
| 681 | if (features.len > 0) { | 716 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); |
| 682 | var start: usize = 0; | 717 | defer llvm_features_buffer.deinit(); |
| 683 | while (start < features.len) { | ||
| 684 | const next_comma_pos = std.mem.indexOfScalar(u8, features[start..], ',') orelse features.len - start; | ||
| 685 | var feature = features[start..start+next_comma_pos]; | ||
| 686 | |||
| 687 | if (feature.len < 2) return .{ .InvalidFeaturesString = {} }; | ||
| 688 | |||
| 689 | if (feature[0] != '+' and feature[0] != '-') return .{ .InvalidFeaturesString = {} }; | ||
| 690 | feature = feature[1..]; | ||
| 691 | |||
| 692 | var found_feature = false; | ||
| 693 | for (known_features) |known_feature| { | ||
| 694 | if (std.mem.eql(u8, feature, known_feature.name)) { | ||
| 695 | found_feature = true; | ||
| 696 | break; | ||
| 697 | } | ||
| 698 | } | ||
| 699 | 718 | ||
| 700 | if (!found_feature) return .{ .InvalidFeature = feature }; | 719 | for (features_slice) |feature| { |
| 720 | try llvm_features_buffer.append("+"); | ||
| 721 | try llvm_features_buffer.append(feature.llvm_name); | ||
| 722 | try llvm_features_buffer.append(","); | ||
| 723 | } | ||
| 701 | 724 | ||
| 702 | start += next_comma_pos + 1; | 725 | const ptr = try allocator.create(Stage2TargetDetails); |
| 703 | } | 726 | ptr.* = Stage2TargetDetails{ |
| 727 | .allocator = allocator, | ||
| 728 | .target_details = std.target.TargetDetails{ | ||
| 729 | .features = features_slice, | ||
| 730 | }, | ||
| 731 | .llvm_cpu_str = "", | ||
| 732 | .llvm_features_str = llvm_features_buffer.toOwnedSlice(), | ||
| 733 | }; | ||
| 734 | |||
| 735 | return ptr; | ||
| 736 | } | ||
| 737 | |||
| 738 | // ABI warning | ||
| 739 | export fn stage2_target_details_get_cache_str(target_details: ?*const Stage2TargetDetails) [*:0]const u8 { | ||
| 740 | if (target_details) |td| { | ||
| 741 | return @as([*:0]const u8, switch (td.target_details) { | ||
| 742 | .cpu => td.llvm_cpu_str, | ||
| 743 | .features => td.llvm_features_str, | ||
| 744 | }); | ||
| 745 | } | ||
| 746 | |||
| 747 | return @as([*:0]const u8, ""); | ||
| 748 | } | ||
| 749 | |||
| 750 | // ABI warning | ||
| 751 | export fn stage2_target_details_get_llvm_cpu(target_details: ?*const Stage2TargetDetails) [*:0]const u8 { | ||
| 752 | if (target_details) |td| { | ||
| 753 | return @as([*:0]const u8, td.llvm_cpu_str); | ||
| 754 | } | ||
| 755 | |||
| 756 | return @as([*:0]const u8, ""); | ||
| 757 | } | ||
| 758 | |||
| 759 | // ABI warning | ||
| 760 | export fn stage2_target_details_get_llvm_features(target_details: ?*const Stage2TargetDetails) [*:0]const u8 { | ||
| 761 | if (target_details) |td| { | ||
| 762 | return @as([*:0]const u8, td.llvm_features_str); | ||
| 704 | } | 763 | } |
| 705 | 764 | ||
| 706 | return .{ .Ok = {} }; | 765 | return @as([*:0]const u8, ""); |
| 707 | } | 766 | } |
src/all_types.hpp+1-2| ... | @@ -2216,8 +2216,7 @@ struct CodeGen { | ... | @@ -2216,8 +2216,7 @@ struct CodeGen { |
| 2216 | const char **clang_argv; | 2216 | const char **clang_argv; |
| 2217 | size_t clang_argv_len; | 2217 | size_t clang_argv_len; |
| 2218 | 2218 | ||
| 2219 | const char *llvm_cpu; | 2219 | Stage2TargetDetails *target_details; |
| 2220 | const char *llvm_features; | ||
| 2221 | }; | 2220 | }; |
| 2222 | 2221 | ||
| 2223 | struct ZigVar { | 2222 | struct ZigVar { |
src/codegen.cpp+12-11| ... | @@ -8655,8 +8655,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { | ... | @@ -8655,8 +8655,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8655 | cache_bool(&cache_hash, g->valgrind_support); | 8655 | cache_bool(&cache_hash, g->valgrind_support); |
| 8656 | cache_bool(&cache_hash, g->link_eh_frame_hdr); | 8656 | cache_bool(&cache_hash, g->link_eh_frame_hdr); |
| 8657 | cache_int(&cache_hash, detect_subsystem(g)); | 8657 | cache_int(&cache_hash, detect_subsystem(g)); |
| 8658 | if (g->llvm_cpu) cache_str(&cache_hash, g->llvm_cpu); | 8658 | |
| 8659 | if (g->llvm_features) cache_str(&cache_hash, g->llvm_features); | 8659 | if (g->target_details) { |
| 8660 | cache_str(&cache_hash, stage2_target_details_get_cache_str(g->target_details)); | ||
| 8661 | } | ||
| 8660 | 8662 | ||
| 8661 | Buf digest = BUF_INIT; | 8663 | Buf digest = BUF_INIT; |
| 8662 | buf_resize(&digest, 0); | 8664 | buf_resize(&digest, 0); |
| ... | @@ -8802,15 +8804,12 @@ static void init(CodeGen *g) { | ... | @@ -8802,15 +8804,12 @@ static void init(CodeGen *g) { |
| 8802 | target_specific_features = ""; | 8804 | target_specific_features = ""; |
| 8803 | } | 8805 | } |
| 8804 | 8806 | ||
| 8805 | // Override CPU and features if non-null. | 8807 | // Override CPU and features if defined by user. |
| 8806 | if (g->llvm_cpu != nullptr) { | 8808 | if (g->target_details) { |
| 8807 | target_specific_cpu_args = g->llvm_cpu; | 8809 | target_specific_cpu_args = stage2_target_details_get_llvm_cpu(g->target_details); |
| 8810 | target_specific_features = stage2_target_details_get_llvm_features(g->target_details); | ||
| 8808 | } | 8811 | } |
| 8809 | 8812 | ||
| 8810 | if (g->llvm_features != nullptr) { | ||
| 8811 | target_specific_features = g->llvm_features; | ||
| 8812 | } | ||
| 8813 | |||
| 8814 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), | 8813 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), |
| 8815 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, | 8814 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, |
| 8816 | LLVMCodeModelDefault, g->function_sections); | 8815 | LLVMCodeModelDefault, g->function_sections); |
| ... | @@ -10390,8 +10389,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10390,8 +10389,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10390 | } | 10389 | } |
| 10391 | cache_buf_opt(ch, g->dynamic_linker_path); | 10390 | cache_buf_opt(ch, g->dynamic_linker_path); |
| 10392 | cache_buf_opt(ch, g->version_script_path); | 10391 | cache_buf_opt(ch, g->version_script_path); |
| 10393 | if (g->llvm_cpu) cache_str(ch, g->llvm_cpu); | 10392 | |
| 10394 | if (g->llvm_features) cache_str(ch, g->llvm_features); | 10393 | if (g->target_details) { |
| 10394 | cache_str(ch, stage2_target_details_get_cache_str(g->target_details)); | ||
| 10395 | } | ||
| 10395 | 10396 | ||
| 10396 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash | 10397 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash |
| 10397 | gen_c_objects(g); | 10398 | gen_c_objects(g); |
src/main.cpp+19-6| ... | @@ -535,8 +535,8 @@ int main(int argc, char **argv) { | ... | @@ -535,8 +535,8 @@ int main(int argc, char **argv) { |
| 535 | WantStackCheck want_stack_check = WantStackCheckAuto; | 535 | WantStackCheck want_stack_check = WantStackCheckAuto; |
| 536 | WantCSanitize want_sanitize_c = WantCSanitizeAuto; | 536 | WantCSanitize want_sanitize_c = WantCSanitizeAuto; |
| 537 | bool function_sections = false; | 537 | bool function_sections = false; |
| 538 | const char *cpu = ""; | 538 | const char *cpu = nullptr; |
| 539 | const char *features = ""; | 539 | const char *features = nullptr; |
| 540 | 540 | ||
| 541 | const char *targets_list_features_arch = nullptr; | 541 | const char *targets_list_features_arch = nullptr; |
| 542 | const char *targets_list_cpus_arch = nullptr; | 542 | const char *targets_list_cpus_arch = nullptr; |
| ... | @@ -1278,12 +1278,25 @@ int main(int argc, char **argv) { | ... | @@ -1278,12 +1278,25 @@ int main(int argc, char **argv) { |
| 1278 | codegen_add_rpath(g, rpath_list.at(i)); | 1278 | codegen_add_rpath(g, rpath_list.at(i)); |
| 1279 | } | 1279 | } |
| 1280 | 1280 | ||
| 1281 | if (!stage2_validate_cpu_and_features(target_arch_name(target.arch), cpu, features)) { | 1281 | Stage2TargetDetails *target_details = nullptr; |
| 1282 | return 1; | 1282 | if (cpu && features) { |
| 1283 | fprintf(stderr, "--cpu and --features options not allowed together\n"); | ||
| 1284 | return main_exit(root_progress_node, EXIT_FAILURE); | ||
| 1285 | } else if (cpu) { | ||
| 1286 | target_details = stage2_target_details_parse_cpu(target_arch_name(target.arch), cpu); | ||
| 1287 | if (!target_details) { | ||
| 1288 | fprintf(stderr, "invalid --cpu value\n"); | ||
| 1289 | return main_exit(root_progress_node, EXIT_FAILURE); | ||
| 1290 | } | ||
| 1291 | } else if (features) { | ||
| 1292 | target_details = stage2_target_details_parse_features(target_arch_name(target.arch), features); | ||
| 1293 | if (!target_details) { | ||
| 1294 | fprintf(stderr, "invalid --features value\n"); | ||
| 1295 | return main_exit(root_progress_node, EXIT_FAILURE); | ||
| 1296 | } | ||
| 1283 | } | 1297 | } |
| 1284 | 1298 | ||
| 1285 | g->llvm_cpu = cpu; | 1299 | g->target_details = target_details; |
| 1286 | g->llvm_features = features; | ||
| 1287 | 1300 | ||
| 1288 | codegen_set_rdynamic(g, rdynamic); | 1301 | codegen_set_rdynamic(g, rdynamic); |
| 1289 | if (mmacosx_version_min && mios_version_min) { | 1302 | if (mmacosx_version_min && mios_version_min) { |
src/userland.cpp+15-1| ... | @@ -91,4 +91,18 @@ void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_coun | ... | @@ -91,4 +91,18 @@ void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_coun |
| 91 | 91 | ||
| 92 | void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {} | 92 | void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {} |
| 93 | void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {} | 93 | void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {} |
| 94 | bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features) { return true; } | 94 | Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str) { |
| 95 | return nullptr; | ||
| 96 | } | ||
| 97 | Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str) { | ||
| 98 | return nullptr; | ||
| 99 | } | ||
| 100 | const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details) { | ||
| 101 | return ""; | ||
| 102 | } | ||
| 103 | const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details) { | ||
| 104 | return ""; | ||
| 105 | } | ||
| 106 | const char *stage2_target_details_get_llvm_features(const Stage2TargetDetails *target_details) { | ||
| 107 | return ""; | ||
| 108 | } |
src/userland.h+16-1| ... | @@ -181,6 +181,21 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_ | ... | @@ -181,6 +181,21 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_ |
| 181 | ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures); | 181 | ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures); |
| 182 | 182 | ||
| 183 | // ABI warning | 183 | // ABI warning |
| 184 | ZIG_EXTERN_C bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features); | 184 | struct Stage2TargetDetails; |
| 185 | |||
| 186 | // ABI warning | ||
| 187 | ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str); | ||
| 188 | |||
| 189 | // ABI warning | ||
| 190 | ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str); | ||
| 191 | |||
| 192 | // ABI warning | ||
| 193 | ZIG_EXTERN_C const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details); | ||
| 194 | |||
| 195 | // ABI warning | ||
| 196 | ZIG_EXTERN_C const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details); | ||
| 197 | |||
| 198 | // ABI warning | ||
| 199 | ZIG_EXTERN_C const char *stage2_target_details_get_llvm_features(const Stage2TargetDetails *target_details); | ||
| 185 | 200 | ||
| 186 | #endif | 201 | #endif |