aboutsummaryrefslogtreecommitdiff
path: root/lib/std/build.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-22 17:13:31 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-01-22 17:13:31 -0500
commit48c7e6c48b81e6e0423b3e4aea238402189eecb7 (patch)
tree1d585eaa73a43b473809ffdc85b4207e2e72ee9c /lib/std/build.zig
parentc6bfece1d54c54024397d7aff9f25087cc4dbfda (diff)
downloadzig-48c7e6c48b81e6e0423b3e4aea238402189eecb7.tar.gz
zig-48c7e6c48b81e6e0423b3e4aea238402189eecb7.zip
std.Target.CpuFeatures is now a struct with both CPU and feature set
Previously it was a tagged union which was one of: * baseline * a specific CPU * a set of features Now, it's possible to have a CPU but also modify the CPU's feature set on top of that. This is closer to what LLVM does. This is more correct because Zig's notion of CPUs (and LLVM's) is not exact CPU models. For example "skylake" is not one very specific model; there are several different pieces of hardware that match "skylake" that have different feature sets enabled.
Diffstat (limited to 'lib/std/build.zig')
-rw-r--r--lib/std/build.zig52
1 files changed, 35 insertions, 17 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig
index a36818fb29..ac6ca30494 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -484,6 +484,7 @@ pub const Builder = struct {
.arch = builtin.arch,
.os = builtin.os,
.abi = builtin.abi,
+ .cpu_features = builtin.cpu_features,
},
}).linuxTriple(self.allocator);
@@ -1375,6 +1376,7 @@ pub const LibExeObjStep = struct {
.arch = target_arch,
.os = target_os,
.abi = target_abi,
+ .cpu_features = target_arch.getBaselineCpuFeatures(),
},
});
}
@@ -1972,25 +1974,41 @@ pub const LibExeObjStep = struct {
try zig_args.append("-target");
try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
- switch (cross.cpu_features) {
- .baseline => {},
- .cpu => |cpu| {
+ const all_features = self.target.getArch().allFeaturesList();
+ var populated_cpu_features = cross.cpu_features.cpu.features;
+ populated_cpu_features.populateDependencies(all_features);
+
+ if (populated_cpu_features.eql(cross.cpu_features.features)) {
+ // The CPU name alone is sufficient.
+ // If it is the baseline CPU, no command line args are required.
+ if (cross.cpu_features.cpu != self.target.getArch().getBaselineCpuFeatures().cpu) {
try zig_args.append("-target-cpu");
- try zig_args.append(cpu.name);
- },
- .features => |features| {
- try zig_args.append("-target-cpu-features");
-
- var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
- for (self.target.getArch().allFeaturesList()) |feature, i| {
- if (features.isEnabled(@intCast(Target.Cpu.Feature.Set.Index, i))) {
- try feature_str_buffer.append(feature.name);
- try feature_str_buffer.append(",");
- }
+ try zig_args.append(cross.cpu_features.cpu.name);
+ }
+ } else {
+ try zig_args.append("-target-cpu");
+ try zig_args.append(cross.cpu_features.cpu.name);
+
+ try zig_args.append("-target-feature");
+ var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
+ for (all_features) |feature, i_usize| {
+ const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
+ const in_cpu_set = populated_cpu_features.isEnabled(i);
+ const in_actual_set = cross.cpu_features.features.isEnabled(i);
+ if (in_cpu_set and !in_actual_set) {
+ try feature_str_buffer.appendByte('-');
+ try feature_str_buffer.append(feature.name);
+ try feature_str_buffer.appendByte(',');
+ } else if (!in_cpu_set and in_actual_set) {
+ try feature_str_buffer.appendByte('+');
+ try feature_str_buffer.append(feature.name);
+ try feature_str_buffer.appendByte(',');
}
-
- try zig_args.append(feature_str_buffer.toSlice());
- },
+ }
+ if (mem.endsWith(u8, feature_str_buffer.toSliceConst(), ",")) {
+ feature_str_buffer.shrink(feature_str_buffer.len() - 1);
+ }
+ try zig_args.append(feature_str_buffer.toSliceConst());
}
},
}