diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-06-11 17:03:46 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-11 17:03:46 -0400 |
| commit | f7361970b334faf4433b3bd1d5dd6d499860c288 (patch) | |
| tree | 7e1b177c8e28979af2ceb306c71e2337a67f5b8e | |
| parent | 45212e3b33151b016ae4a597a898db0cc13d4e6b (diff) | |
| parent | da4081fe21f534157a7a88e2d6b2b6a80ee2f32d (diff) | |
| download | zig-f7361970b334faf4433b3bd1d5dd6d499860c288.tar.gz zig-f7361970b334faf4433b3bd1d5dd6d499860c288.zip | |
Merge pull request #8060 from DrDeano/feature/add-mcpu-to-target-options
Add CPU feature check to standardTargetOptions
| -rw-r--r-- | lib/std/build.zig | 62 | ||||
| -rw-r--r-- | lib/std/target.zig | 11 |
2 files changed, 62 insertions, 11 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index 12c98271d5..2b8ad8839a 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -637,7 +637,7 @@ pub const Builder = struct { "target", "The CPU architecture, OS, and ABI to build for", ); - const mcpu = self.option([]const u8, "cpu", "Target CPU"); + const mcpu = self.option([]const u8, "cpu", "Target CPU features to add or subtract"); const triple = maybe_triple orelse return args.default_target; @@ -699,20 +699,64 @@ pub const Builder = struct { if (args.whitelist) |list| whitelist_check: { // Make sure it's a match of one of the list. + var mismatch_triple = true; + var mismatch_cpu_features = true; + var whitelist_item = CrossTarget{}; for (list) |t| { + mismatch_cpu_features = true; + mismatch_triple = true; + const t_triple = t.zigTriple(self.allocator) catch unreachable; if (mem.eql(u8, t_triple, selected_canonicalized_triple)) { - break :whitelist_check; + mismatch_triple = false; + whitelist_item = t; + if (t.getCpuFeatures().isSuperSetOf(selected_target.getCpuFeatures())) { + mismatch_cpu_features = false; + break :whitelist_check; + } else { + break; + } } } - warn("Chosen target '{s}' does not match one of the supported targets:\n", .{ - selected_canonicalized_triple, - }); - for (list) |t| { - const t_triple = t.zigTriple(self.allocator) catch unreachable; - warn(" {s}\n", .{t_triple}); + if (mismatch_triple) { + warn("Chosen target '{s}' does not match one of the supported targets:\n", .{ + selected_canonicalized_triple, + }); + for (list) |t| { + const t_triple = t.zigTriple(self.allocator) catch unreachable; + warn(" {s}\n", .{t_triple}); + } + warn("\n", .{}); + } else { + assert(mismatch_cpu_features); + const whitelist_cpu = whitelist_item.getCpu(); + const selected_cpu = selected_target.getCpu(); + warn("Chosen CPU model '{s}' does not match one of the supported targets:\n", .{ + selected_cpu.model.name, + }); + warn(" Supported feature Set: ", .{}); + const all_features = whitelist_cpu.arch.allFeaturesList(); + var populated_cpu_features = whitelist_cpu.model.features; + populated_cpu_features.populateDependencies(all_features); + for (all_features) |feature, i_usize| { + const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize); + const in_cpu_set = populated_cpu_features.isEnabled(i); + if (in_cpu_set) { + warn("{s} ", .{feature.name}); + } + } + warn("\n", .{}); + warn(" Remove: ", .{}); + for (all_features) |feature, i_usize| { + const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize); + const in_cpu_set = populated_cpu_features.isEnabled(i); + const in_actual_set = selected_cpu.features.isEnabled(i); + if (in_actual_set and !in_cpu_set) { + warn("{s} ", .{feature.name}); + } + } + warn("\n", .{}); } - warn("\n", .{}); self.markInvalidUserInput(); return args.default_target; } diff --git a/lib/std/target.zig b/lib/std/target.zig index 3fd5cd5f94..faebe665ab 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -664,8 +664,15 @@ pub const Target = struct { return @ptrCast(*const [byte_count]u8, &set.ints); } - pub fn eql(set: Set, other: Set) bool { - return mem.eql(usize, &set.ints, &other.ints); + pub fn eql(set: Set, other_set: Set) bool { + return mem.eql(usize, &set.ints, &other_set.ints); + } + + pub fn isSuperSetOf(set: Set, other_set: Set) bool { + const V = std.meta.Vector(usize_count, usize); + const set_v: V = set.ints; + const other_v: V = other_set.ints; + return @reduce(.And, (set_v & other_v) == other_v); } }; |
