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
signature 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...@@ -531,12 +531,12 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
531531
532// ABI warning532// ABI warning
533export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {533export 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| {
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}
538538
539fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {539fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void {
540 const stdout_stream = &std.io.getStdOut().outStream().stream;540 const stdout_stream = &std.io.getStdOut().outStream().stream;
541541
542 const arch = Target.parseArchTag(arch_name) catch {542 const arch = Target.parseArchTag(arch_name) catch {
...@@ -575,12 +575,12 @@ fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void...@@ -575,12 +575,12 @@ fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void
575575
576// ABI warning576// ABI warning
577export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {577export 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| {
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}
582582
583fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {583fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void {
584 const stdout_stream = &std.io.getStdOut().outStream().stream;584 const stdout_stream = &std.io.getStdOut().outStream().stream;
585585
586 const arch = Target.parseArchTag(arch_name) catch {586 const arch = Target.parseArchTag(arch_name) catch {
...@@ -618,3 +618,90 @@ fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {...@@ -618,3 +618,90 @@ fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
618}618}
619619
620// use target_arch_name(ZigLLVM_ArchType) to get name from main.cpp 'target'.620// 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 {...@@ -2215,6 +2215,9 @@ struct CodeGen {
22152215
2216 const char **clang_argv;2216 const char **clang_argv;
2217 size_t clang_argv_len;2217 size_t clang_argv_len;
2218
2219 const char *llvm_cpu;
2220 const char *llvm_features;
2218};2221};
22192222
2220struct ZigVar {2223struct ZigVar {
src/codegen.cpp+9
...@@ -8800,6 +8800,15 @@ static void init(CodeGen *g) {...@@ -8800,6 +8800,15 @@ static void init(CodeGen *g) {
8800 target_specific_features = "";8800 target_specific_features = "";
8801 }8801 }
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
8803 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),8812 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
8804 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,8813 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
8805 LLVMCodeModelDefault, g->function_sections);8814 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) {...@@ -100,6 +100,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
100 " --override-lib-dir [arg] override path to Zig lib directory\n"100 " --override-lib-dir [arg] override path to Zig lib directory\n"
101 " -ffunction-sections places each function in a separate section\n"101 " -ffunction-sections places each function in a separate section\n"
102 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"102 " -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"
103 "\n"105 "\n"
104 "Link Options:\n"106 "Link Options:\n"
105 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"107 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
...@@ -533,6 +535,8 @@ int main(int argc, char **argv) {...@@ -533,6 +535,8 @@ int main(int argc, char **argv) {
533 WantStackCheck want_stack_check = WantStackCheckAuto;535 WantStackCheck want_stack_check = WantStackCheckAuto;
534 WantCSanitize want_sanitize_c = WantCSanitizeAuto;536 WantCSanitize want_sanitize_c = WantCSanitizeAuto;
535 bool function_sections = false;537 bool function_sections = false;
538 const char *cpu = "";
539 const char *features = "";
536540
537 const char *targets_list_features_arch = nullptr;541 const char *targets_list_features_arch = nullptr;
538 const char *targets_list_cpus_arch = nullptr;542 const char *targets_list_cpus_arch = nullptr;
...@@ -951,6 +955,10 @@ int main(int argc, char **argv) {...@@ -951,6 +955,10 @@ int main(int argc, char **argv) {
951 targets_list_features_arch = argv[i];955 targets_list_features_arch = argv[i];
952 } else if (strcmp(arg, "--list-cpus") == 0) {956 } else if (strcmp(arg, "--list-cpus") == 0) {
953 targets_list_cpus_arch = argv[i];957 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];
954 }else {962 }else {
955 fprintf(stderr, "Invalid argument: %s\n", arg);963 fprintf(stderr, "Invalid argument: %s\n", arg);
956 return print_error_usage(arg0);964 return print_error_usage(arg0);
...@@ -1248,6 +1256,7 @@ int main(int argc, char **argv) {...@@ -1248,6 +1256,7 @@ int main(int argc, char **argv) {
1248 g->system_linker_hack = system_linker_hack;1256 g->system_linker_hack = system_linker_hack;
1249 g->function_sections = function_sections;1257 g->function_sections = function_sections;
12501258
1259
1251 for (size_t i = 0; i < lib_dirs.length; i += 1) {1260 for (size_t i = 0; i < lib_dirs.length; i += 1) {
1252 codegen_add_lib_dir(g, lib_dirs.at(i));1261 codegen_add_lib_dir(g, lib_dirs.at(i));
1253 }1262 }
...@@ -1269,6 +1278,13 @@ int main(int argc, char **argv) {...@@ -1269,6 +1278,13 @@ int main(int argc, char **argv) {
1269 codegen_add_rpath(g, rpath_list.at(i));1278 codegen_add_rpath(g, rpath_list.at(i));
1270 }1279 }
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
1272 codegen_set_rdynamic(g, rdynamic);1288 codegen_set_rdynamic(g, rdynamic);
1273 if (mmacosx_version_min && mios_version_min) {1289 if (mmacosx_version_min && mios_version_min) {
1274 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");1290 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...@@ -91,3 +91,4 @@ void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_coun
9191
92void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}92void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
93void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}93void 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_...@@ -180,4 +180,7 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_
180// ABI warning180// ABI warning
181ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures);181ZIG_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
183#endif186#endif