authorgravatar for lgustaf1@binghamton.eduLayne Gustafson <lgustaf1@binghamton.edu> 2020-01-08 20:27:36-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-19 20:53:19-05:00
logc61856ebcf54a55f1c17a5fd6a3b3300115b2c65
tree16c00869a16f4c80f697be2822bbfa80c1b04cef
parent79a2747de490ca2bb1603fd1ce55637fb5278671
signaturelock-open Commit is signed but in an unrecognized format.

Add TargetDetails abstraction


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 {
11991199
1200 subsystem: ?builtin.SubSystem = null,1200 subsystem: ?builtin.SubSystem = null,
12011201
1202 cpu: ?[]const u8 = null,1202 target_details: ?std.target.TargetDetails = null,
1203 features: ?[]const u8 = null,
12041203
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 }
13891388
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 }
14061392
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 }
19961982
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");
20011987 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 }
20061998
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");
860860
861pub const Feature = struct {861pub const Feature = struct {
862 name: []const u8,862 name: []const u8,
863 llvm_name: []const u8,
863 description: []const u8,864 description: []const u8,
864865
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};
874875
876pub const TargetDetails = union(enum) {
877 cpu: *const Cpu,
878 features: []*const Feature,
879};
880
875pub fn getFeaturesForArch(arch: @TagType(Target.Arch)) []*const Feature {881pub 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}
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_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}
538538
539fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void {539fn 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;
541541
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 {
565565
566 try stdout_stream.print(" - {}\n", .{ feature.description });566 try stdout_stream.print(" - {}\n", .{ feature.description });
567567
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}
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_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}
582582
583fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void {583fn 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;
585585
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 {
609609
610 try stdout_stream.write("\n");610 try stdout_stream.write("\n");
611611
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}
619619
620// use target_arch_name(ZigLLVM_ArchType) to get name from main.cpp 'target'.620const 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 warning628// ABI warning
622export fn stage2_validate_cpu_and_features(629export 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
645export 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}
631657
632 const res = validateCpuAndFeatures(658fn 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 "");
636660
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}
654678
655const ValidateCpuAndFeaturesResult = union(enum) {679 return error.InvalidCpu;
656 Ok,680}
657 InvalidCpu: []const u8,
658 InvalidFeaturesString,
659 InvalidFeature: []const u8,
660};
661681
662fn validateCpuAndFeatures(arch: @TagType(std.Target.Arch), cpu: []const u8, features: []const u8) ValidateCpuAndFeaturesResult {682fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails {
683 const allocator = std.heap.c_allocator;
663684
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 }
675706
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();
680715
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 }
699718
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 }
701724
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
739export 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
751export 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
760export 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 }
705764
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;
22182218
2219 const char *llvm_cpu;2219 Stage2TargetDetails *target_details;
2220 const char *llvm_features;
2221};2220};
22222221
2223struct ZigVar {2222struct 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 }
86608662
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 }
88048806
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 }
1039510396
10396 // gen_c_objects appends objects to g->link_objects which we want to include in the hash10397 // 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;
540540
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 }
12801280
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 }
12841298
1285 g->llvm_cpu = cpu;1299 g->target_details = target_details;
1286 g->llvm_features = features;
12871300
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
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; }94Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str) {
95 return nullptr;
96}
97Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str) {
98 return nullptr;
99}
100const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details) {
101 return "";
102}
103const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details) {
104 return "";
105}
106const 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_
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 warning183// ABI warning
184ZIG_EXTERN_C bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features);184struct Stage2TargetDetails;
185
186// ABI warning
187ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str);
188
189// ABI warning
190ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str);
191
192// ABI warning
193ZIG_EXTERN_C const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details);
194
195// ABI warning
196ZIG_EXTERN_C const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details);
197
198// ABI warning
199ZIG_EXTERN_C const char *stage2_target_details_get_llvm_features(const Stage2TargetDetails *target_details);
185200
186#endif201#endif