| author | |
| committer | |
| log | c61856ebcf54a55f1c17a5fd6a3b3300115b2c65 |
| tree | 16c00869a16f4c80f697be2822bbfa80c1b04cef |
| parent | 79a2747de490ca2bb1603fd1ce55637fb5278671 |
| signature |
8 files changed, 223 insertions(+), 124 deletions(-)
lib/std/build.zig+17-25| ... | ... | @@ -1199,8 +1199,7 @@ pub const LibExeObjStep = struct { |
| 1199 | 1199 | |
| 1200 | 1200 | subsystem: ?builtin.SubSystem = null, |
| 1201 | 1201 | |
| 1202 | cpu: ?[]const u8 = null, | |
| 1203 | features: ?[]const u8 = null, | |
| 1202 | target_details: ?std.target.TargetDetails = null, | |
| 1204 | 1203 | |
| 1205 | 1204 | const LinkObject = union(enum) { |
| 1206 | 1205 | StaticPath: []const u8, |
| ... | ... | @@ -1387,21 +1386,8 @@ pub const LibExeObjStep = struct { |
| 1387 | 1386 | self.computeOutFileNames(); |
| 1388 | 1387 | } |
| 1389 | 1388 | |
| 1390 | pub fn setCpu(self: *LibExeObjStep, cpu: *const std.target.Cpu) void { | |
| 1391 | self.cpu = cpu.name; | |
| 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(); | |
| 1389 | pub fn setTargetDetails(self: *LibExeObjStep, target_details: std.target.TargetDetails) void { | |
| 1390 | self.target_details = target_details; | |
| 1405 | 1391 | } |
| 1406 | 1392 | |
| 1407 | 1393 | pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void { |
| ... | ... | @@ -1994,14 +1980,20 @@ pub const LibExeObjStep = struct { |
| 1994 | 1980 | }, |
| 1995 | 1981 | } |
| 1996 | 1982 | |
| 1997 | if (self.cpu) |cpu| { | |
| 1998 | try zig_args.append("--cpu"); | |
| 1999 | try zig_args.append(cpu); | |
| 2000 | } | |
| 2001 | ||
| 2002 | if (self.features) |features| { | |
| 2003 | try zig_args.append("--features"); | |
| 2004 | try zig_args.append(features); | |
| 1983 | if (self.target_details) |td| { | |
| 1984 | switch (td) { | |
| 1985 | .cpu => |cpu| { | |
| 1986 | try zig_args.append("--cpu"); | |
| 1987 | try zig_args.append(cpu.name); | |
| 1988 | }, | |
| 1989 | .features => |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 | 1999 | if (self.target_glibc) |ver| { |
lib/std/target.zig+6| ... | ... | @@ -860,6 +860,7 @@ pub const x86 = @import("target/x86.zig"); |
| 860 | 860 | |
| 861 | 861 | pub const Feature = struct { |
| 862 | 862 | name: []const u8, |
| 863 | llvm_name: []const u8, | |
| 863 | 864 | description: []const u8, |
| 864 | 865 | |
| 865 | 866 | dependencies: []*const Feature, |
| ... | ... | @@ -872,6 +873,11 @@ pub const Cpu = struct { |
| 872 | 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 | 881 | pub fn getFeaturesForArch(arch: @TagType(Target.Arch)) []*const Feature { |
| 876 | 882 | return switch (arch) { |
| 877 | 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 | 530 | } |
| 531 | 531 | |
| 532 | 532 | // ABI warning |
| 533 | export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void { | |
| 534 | printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| { | |
| 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_dependencies) catch |err| { | |
| 535 | 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 | 540 | const stdout_stream = &std.io.getStdOut().outStream().stream; |
| 541 | 541 | |
| 542 | 542 | const arch = Target.parseArchTag(arch_name) catch { |
| ... | ... | @@ -565,22 +565,22 @@ fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void { |
| 565 | 565 | |
| 566 | 566 | try stdout_stream.print(" - {}\n", .{ feature.description }); |
| 567 | 567 | |
| 568 | if (show_subfeatures and feature.subfeatures.len > 0) { | |
| 569 | for (feature.subfeatures) |subfeature| { | |
| 570 | try stdout_stream.print(" {}\n", .{ subfeature.name }); | |
| 568 | if (show_dependencies and feature.dependencies.len > 0) { | |
| 569 | for (feature.dependencies) |dependency| { | |
| 570 | try stdout_stream.print(" {}\n", .{ dependency.name }); | |
| 571 | 571 | } |
| 572 | 572 | } |
| 573 | 573 | } |
| 574 | 574 | } |
| 575 | 575 | |
| 576 | 576 | // ABI warning |
| 577 | export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void { | |
| 578 | printCpusForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| { | |
| 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_dependencies) catch |err| { | |
| 579 | 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 | 584 | const stdout_stream = &std.io.getStdOut().outStream().stream; |
| 585 | 585 | |
| 586 | 586 | const arch = Target.parseArchTag(arch_name) catch { |
| ... | ... | @@ -609,99 +609,158 @@ fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void { |
| 609 | 609 | |
| 610 | 610 | try stdout_stream.write("\n"); |
| 611 | 611 | |
| 612 | if (show_subfeatures and cpu.subfeatures.len > 0) { | |
| 613 | for (cpu.subfeatures) |subfeature| { | |
| 614 | try stdout_stream.print(" {}\n", .{ subfeature.name }); | |
| 612 | if (show_dependencies and cpu.dependencies.len > 0) { | |
| 613 | for (cpu.dependencies) |dependency| { | |
| 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 | 628 | // ABI warning |
| 622 | export fn stage2_validate_cpu_and_features( | |
| 623 | arch_name: [*:0]const u8, | |
| 624 | cpu: ?[*:0]const u8, | |
| 625 | features: ?[*:0]const u8, | |
| 626 | ) bool { | |
| 627 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_name)) catch { | |
| 628 | std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{ arch_name }); | |
| 629 | return false; | |
| 629 | export fn stage2_target_details_parse_cpu(arch_str: ?[*:0]const u8, cpu_str: ?[*:0]const u8) ?*Stage2TargetDetails { | |
| 630 | if (cpu_str == null) return null; | |
| 631 | if (arch_str == null) return null; | |
| 632 | ||
| 633 | const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch { | |
| 634 | return null; | |
| 635 | }; | |
| 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( | |
| 633 | 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 ""); | |
| 658 | fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails { | |
| 659 | const cpus = std.target.getCpusForArch(arch); | |
| 636 | 660 | |
| 637 | switch (res) { | |
| 638 | .Ok => return true, | |
| 639 | .InvalidCpu => |invalid_cpu| { | |
| 640 | std.debug.warn("Invalid CPU '{}'\n", .{ invalid_cpu }); | |
| 641 | return false; | |
| 642 | }, | |
| 643 | .InvalidFeaturesString => { | |
| 644 | std.debug.warn("Invalid features string\n", .{}); | |
| 645 | std.debug.warn("Must have format \"+yes_feature,-no_feature\"\n", .{}); | |
| 646 | return false; | |
| 647 | }, | |
| 648 | .InvalidFeature => |invalid_feature| { | |
| 649 | std.debug.warn("Invalid feature '{}'\n", .{ invalid_feature }); | |
| 650 | return false; | |
| 661 | for (cpus) |cpu| { | |
| 662 | if (std.mem.eql(u8, str, cpu.name)) { | |
| 663 | const allocator = std.heap.c_allocator; | |
| 664 | ||
| 665 | const ptr = try allocator.create(Stage2TargetDetails); | |
| 666 | ptr.* = .{ | |
| 667 | .allocator = allocator, | |
| 668 | .target_details = .{ | |
| 669 | .cpu = cpu, | |
| 670 | }, | |
| 671 | .llvm_cpu_str = cpu.name, | |
| 672 | .llvm_features_str = "", | |
| 673 | }; | |
| 674 | ||
| 675 | return ptr; | |
| 651 | 676 | } |
| 652 | 677 | } |
| 653 | } | |
| 654 | 678 | |
| 655 | const ValidateCpuAndFeaturesResult = union(enum) { | |
| 656 | Ok, | |
| 657 | InvalidCpu: []const u8, | |
| 658 | InvalidFeaturesString, | |
| 659 | InvalidFeature: []const u8, | |
| 660 | }; | |
| 679 | return error.InvalidCpu; | |
| 680 | } | |
| 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 | 685 | const known_features = std.target.getFeaturesForArch(arch); |
| 666 | ||
| 667 | if (cpu.len > 0) { | |
| 668 | var found_cpu = false; | |
| 669 | for (known_cpus) |known_cpu| { | |
| 670 | if (std.mem.eql(u8, cpu, known_cpu.name)) { | |
| 671 | found_cpu = true; | |
| 686 | ||
| 687 | var features = std.ArrayList(*const std.target.Feature).init(allocator); | |
| 688 | defer features.deinit(); | |
| 689 | ||
| 690 | var start: usize = 0; | |
| 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 | 703 | break; |
| 673 | 704 | } |
| 674 | 705 | } |
| 675 | 706 | |
| 676 | if (!found_cpu) { | |
| 677 | return .{ .InvalidCpu = cpu }; | |
| 707 | if (feature) |f| { | |
| 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) { | |
| 682 | var start: usize = 0; | |
| 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 | } | |
| 716 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | |
| 717 | defer llvm_features_buffer.deinit(); | |
| 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; | |
| 703 | } | |
| 725 | const ptr = try allocator.create(Stage2TargetDetails); | |
| 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 | 2216 | const char **clang_argv; |
| 2217 | 2217 | size_t clang_argv_len; |
| 2218 | 2218 | |
| 2219 | const char *llvm_cpu; | |
| 2220 | const char *llvm_features; | |
| 2219 | Stage2TargetDetails *target_details; | |
| 2221 | 2220 | }; |
| 2222 | 2221 | |
| 2223 | 2222 | struct ZigVar { |
src/codegen.cpp+12-11| ... | ... | @@ -8655,8 +8655,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8655 | 8655 | cache_bool(&cache_hash, g->valgrind_support); |
| 8656 | 8656 | cache_bool(&cache_hash, g->link_eh_frame_hdr); |
| 8657 | 8657 | cache_int(&cache_hash, detect_subsystem(g)); |
| 8658 | if (g->llvm_cpu) cache_str(&cache_hash, g->llvm_cpu); | |
| 8659 | if (g->llvm_features) cache_str(&cache_hash, g->llvm_features); | |
| 8658 | ||
| 8659 | if (g->target_details) { | |
| 8660 | cache_str(&cache_hash, stage2_target_details_get_cache_str(g->target_details)); | |
| 8661 | } | |
| 8660 | 8662 | |
| 8661 | 8663 | Buf digest = BUF_INIT; |
| 8662 | 8664 | buf_resize(&digest, 0); |
| ... | ... | @@ -8802,15 +8804,12 @@ static void init(CodeGen *g) { |
| 8802 | 8804 | target_specific_features = ""; |
| 8803 | 8805 | } |
| 8804 | 8806 | |
| 8805 | // Override CPU and features if non-null. | |
| 8806 | if (g->llvm_cpu != nullptr) { | |
| 8807 | target_specific_cpu_args = g->llvm_cpu; | |
| 8807 | // Override CPU and features if defined by user. | |
| 8808 | if (g->target_details) { | |
| 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 | 8813 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), |
| 8815 | 8814 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, |
| 8816 | 8815 | LLVMCodeModelDefault, g->function_sections); |
| ... | ... | @@ -10390,8 +10389,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10390 | 10389 | } |
| 10391 | 10390 | cache_buf_opt(ch, g->dynamic_linker_path); |
| 10392 | 10391 | cache_buf_opt(ch, g->version_script_path); |
| 10393 | if (g->llvm_cpu) cache_str(ch, g->llvm_cpu); | |
| 10394 | if (g->llvm_features) cache_str(ch, g->llvm_features); | |
| 10392 | ||
| 10393 | if (g->target_details) { | |
| 10394 | cache_str(ch, stage2_target_details_get_cache_str(g->target_details)); | |
| 10395 | } | |
| 10395 | 10396 | |
| 10396 | 10397 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash |
| 10397 | 10398 | gen_c_objects(g); |
src/main.cpp+19-6| ... | ... | @@ -535,8 +535,8 @@ int main(int argc, char **argv) { |
| 535 | 535 | WantStackCheck want_stack_check = WantStackCheckAuto; |
| 536 | 536 | WantCSanitize want_sanitize_c = WantCSanitizeAuto; |
| 537 | 537 | bool function_sections = false; |
| 538 | const char *cpu = ""; | |
| 539 | const char *features = ""; | |
| 538 | const char *cpu = nullptr; | |
| 539 | const char *features = nullptr; | |
| 540 | 540 | |
| 541 | 541 | const char *targets_list_features_arch = nullptr; |
| 542 | 542 | const char *targets_list_cpus_arch = nullptr; |
| ... | ... | @@ -1278,12 +1278,25 @@ int main(int argc, char **argv) { |
| 1278 | 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)) { | |
| 1282 | return 1; | |
| 1281 | Stage2TargetDetails *target_details = nullptr; | |
| 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; | |
| 1286 | g->llvm_features = features; | |
| 1299 | g->target_details = target_details; | |
| 1287 | 1300 | |
| 1288 | 1301 | codegen_set_rdynamic(g, rdynamic); |
| 1289 | 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 | 91 | |
| 92 | 92 | void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {} |
| 93 | 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 | 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 | 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 | 201 | #endif |