diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 17:13:31 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 17:13:31 -0500 |
| commit | 48c7e6c48b81e6e0423b3e4aea238402189eecb7 (patch) | |
| tree | 1d585eaa73a43b473809ffdc85b4207e2e72ee9c /lib/std/build.zig | |
| parent | c6bfece1d54c54024397d7aff9f25087cc4dbfda (diff) | |
| download | zig-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.zig | 52 |
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()); } }, } |
