authorgravatar for lgustaf1@binghamton.eduLayne Gustafson <lgustaf1@binghamton.edu> 2019-12-20 21:46:42-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-19 20:53:19-05:00
logbd6ef21f8556b3872c5780eee70621e6c66a0aa4
tree8b7c28b324ff41905b26d28c5e0c3441f93c06f0
parentc8f1e0d6d8f3ccfa952e9612903783baa9b2c12f
signaturelock-open Commit is signed but in an unrecognized format.

Add cpu/feature specification to cmndline


6 files changed, 123 insertions(+), 4 deletions(-)

src-self-hosted/stage1.zig+91-4
......@@ -531,12 +531,12 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
531531
532532// ABI warning
533533export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {
534 print_features_for_arch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
534 printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
535535 std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
536536 };
537537}
538538
539fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
539fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void {
540540 const stdout_stream = &std.io.getStdOut().outStream().stream;
541541
542542 const arch = Target.parseArchTag(arch_name) catch {
......@@ -575,12 +575,12 @@ fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void
575575
576576// ABI warning
577577export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {
578 print_cpus_for_arch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
578 printCpusForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
579579 std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
580580 };
581581}
582582
583fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
583fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void {
584584 const stdout_stream = &std.io.getStdOut().outStream().stream;
585585
586586 const arch = Target.parseArchTag(arch_name) catch {
......@@ -618,3 +618,90 @@ fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
618618}
619619
620620// use target_arch_name(ZigLLVM_ArchType) to get name from main.cpp 'target'.
621// ABI warning
622export 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;
630 };
631
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 "");
636
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;
651 }
652 }
653}
654
655const ValidateCpuAndFeaturesResult = union(enum) {
656 Ok,
657 InvalidCpu: []const u8,
658 InvalidFeaturesString,
659 InvalidFeature: []const u8,
660};
661
662fn validateCpuAndFeatures(arch: @TagType(std.Target.Arch), cpu: []const u8, features: []const u8) ValidateCpuAndFeaturesResult {
663
664 const known_cpus = std.target.getCpusForArch(arch);
665 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;
672 break;
673 }
674 }
675
676 if (!found_cpu) {
677 return .{ .InvalidCpu = cpu };
678 }
679 }
680
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 }
699
700 if (!found_feature) return .{ .InvalidFeature = feature };
701
702 start += next_comma_pos + 1;
703 }
704 }
705
706 return .{ .Ok = {} };
707}
src/all_types.hpp+3
......@@ -2215,6 +2215,9 @@ struct CodeGen {
22152215
22162216 const char **clang_argv;
22172217 size_t clang_argv_len;
2218
2219 const char *llvm_cpu;
2220 const char *llvm_features;
22182221};
22192222
22202223struct ZigVar {
src/codegen.cpp+9
......@@ -8800,6 +8800,15 @@ static void init(CodeGen *g) {
88008800 target_specific_features = "";
88018801 }
88028802
8803 // Override CPU and features if non-null.
8804 if (g->llvm_cpu != nullptr) {
8805 target_specific_cpu_args = g->llvm_cpu;
8806 }
8807
8808 if (g->llvm_features != nullptr) {
8809 target_specific_features = g->llvm_features;
8810 }
8811
88038812 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
88048813 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
88058814 LLVMCodeModelDefault, g->function_sections);
src/main.cpp+16
......@@ -100,6 +100,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
100100 " --override-lib-dir [arg] override path to Zig lib directory\n"
101101 " -ffunction-sections places each function in a separate section\n"
102102 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
103 " --cpu [cpu] compile for [cpu] on the current target\n"
104 " --features [feature_str] compile with features in [feature_str] on the current target\n"
103105 "\n"
104106 "Link Options:\n"
105107 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
......@@ -533,6 +535,8 @@ int main(int argc, char **argv) {
533535 WantStackCheck want_stack_check = WantStackCheckAuto;
534536 WantCSanitize want_sanitize_c = WantCSanitizeAuto;
535537 bool function_sections = false;
538 const char *cpu = "";
539 const char *features = "";
536540
537541 const char *targets_list_features_arch = nullptr;
538542 const char *targets_list_cpus_arch = nullptr;
......@@ -951,6 +955,10 @@ int main(int argc, char **argv) {
951955 targets_list_features_arch = argv[i];
952956 } else if (strcmp(arg, "--list-cpus") == 0) {
953957 targets_list_cpus_arch = argv[i];
958 } else if (strcmp(arg, "--cpu") == 0) {
959 cpu = argv[i];
960 } else if (strcmp(arg, "--features") == 0) {
961 features = argv[i];
954962 }else {
955963 fprintf(stderr, "Invalid argument: %s\n", arg);
956964 return print_error_usage(arg0);
......@@ -1248,6 +1256,7 @@ int main(int argc, char **argv) {
12481256 g->system_linker_hack = system_linker_hack;
12491257 g->function_sections = function_sections;
12501258
1259
12511260 for (size_t i = 0; i < lib_dirs.length; i += 1) {
12521261 codegen_add_lib_dir(g, lib_dirs.at(i));
12531262 }
......@@ -1269,6 +1278,13 @@ int main(int argc, char **argv) {
12691278 codegen_add_rpath(g, rpath_list.at(i));
12701279 }
12711280
1281 if (!stage2_validate_cpu_and_features(target_arch_name(target.arch), cpu, features)) {
1282 return 1;
1283 }
1284
1285 g->llvm_cpu = cpu;
1286 g->llvm_features = features;
1287
12721288 codegen_set_rdynamic(g, rdynamic);
12731289 if (mmacosx_version_min && mios_version_min) {
12741290 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
src/userland.cpp+1
......@@ -91,3 +91,4 @@ void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_coun
9191
9292void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
9393void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
94bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features) { return true; }
src/userland.h+3
......@@ -180,4 +180,7 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_
180180// ABI warning
181181ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures);
182182
183// ABI warning
184ZIG_EXTERN_C bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features);
185
183186#endif