Commit 39759b90fc
Changed files (6)
lib/std/target.zig
@@ -631,9 +631,9 @@ pub const Target = union(enum) {
};
}
- pub fn cpuFeaturesList(self: Target) []const *const Cpu.Feature {
+ pub fn cpuFeatureSet(self: Target) Cpu.Feature.Set {
return switch (self.getCpuFeatures()) {
- .baseline => self.arch.baselineFeatures(),
+ .baseline => self.getArch().baselineFeatures(),
.cpu => |cpu| cpu.features,
.features => |features| features,
};
src/main.cpp
@@ -1372,7 +1372,7 @@ int main(int argc, char **argv) {
return main_exit(root_progress_node, EXIT_SUCCESS);
}
case CmdTargets:
- return stage2_cmd_targets();
+ return stage2_cmd_targets(buf_ptr(&zig_triple_buf));
case CmdNone:
return print_full_usage(arg0, stderr, EXIT_FAILURE);
}
src/userland.cpp
@@ -141,7 +141,7 @@ void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features,
*len = strlen(cpu_features->builtin_str);
}
-int stage2_cmd_targets(void) {
+int stage2_cmd_targets(const char *zig_triple) {
const char *msg = "stage0 called stage2_cmd_targets";
stage2_panic(msg, strlen(msg));
}
src/userland.h
@@ -213,7 +213,7 @@ ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatu
const char **ptr, size_t *len);
// ABI warning
-ZIG_EXTERN_C int stage2_cmd_targets(void);
+ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
#endif
src-self-hosted/print_targets.zig
@@ -9,6 +9,7 @@ pub fn cmdTargets(
allocator: *Allocator,
args: []const []const u8,
stdout: *io.OutStream(fs.File.WriteError),
+ native_target: Target,
) !void {
const BOS = io.BufferedOutStream(fs.File.WriteError);
var bos = BOS.init(stdout);
@@ -76,22 +77,34 @@ pub fn cmdTargets(
try jws.objectField("native");
try jws.beginObject();
{
- const triple = try Target.current.zigTriple(allocator);
+ const triple = try native_target.zigTriple(allocator);
defer allocator.free(triple);
try jws.objectField("triple");
try jws.emitString(triple);
}
try jws.objectField("arch");
- try jws.emitString(@tagName(Target.current.getArch()));
+ try jws.emitString(@tagName(native_target.getArch()));
try jws.objectField("os");
- try jws.emitString(@tagName(Target.current.getOs()));
+ try jws.emitString(@tagName(native_target.getOs()));
try jws.objectField("abi");
- try jws.emitString(@tagName(Target.current.getAbi()));
+ try jws.emitString(@tagName(native_target.getAbi()));
try jws.objectField("cpuName");
- switch (Target.current.getCpuFeatures()) {
+ switch (native_target.getCpuFeatures()) {
.baseline, .features => try jws.emitNull(),
.cpu => |cpu| try jws.emitString(cpu.name),
}
+ {
+ try jws.objectField("cpuFeatures");
+ try jws.beginArray();
+ const feature_set = native_target.cpuFeatureSet();
+ for (native_target.getArch().allFeaturesList()) |feature, i| {
+ if (feature_set.isEnabled(@intCast(u8, i))) {
+ try jws.arrayElem();
+ try jws.emitString(feature.name);
+ }
+ }
+ try jws.endArray();
+ }
try jws.endObject();
try jws.endObject();
src-self-hosted/stage1.zig
@@ -539,19 +539,82 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
node.context.maybeRefresh();
}
+fn cpuFeaturesFromLLVM(
+ arch: Target.Arch,
+ llvm_cpu_name_z: ?[*:0]const u8,
+ llvm_cpu_features_opt: ?[*:0]const u8,
+) !Target.CpuFeatures {
+ if (llvm_cpu_name_z) |cpu_name_z| {
+ const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
+
+ for (arch.allCpus()) |cpu| {
+ const this_llvm_name = cpu.llvm_name orelse continue;
+ if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
+ return Target.CpuFeatures{ .cpu = cpu };
+ }
+ }
+ }
+
+ var set = arch.baselineFeatures();
+ const llvm_cpu_features = llvm_cpu_features_opt orelse return Target.CpuFeatures{
+ .features = set,
+ };
+
+ var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
+ while (it.next()) |decorated_llvm_feat| {
+ var op: enum {
+ add,
+ sub,
+ } = undefined;
+ var llvm_feat: []const u8 = undefined;
+ if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
+ op = .add;
+ llvm_feat = decorated_llvm_feat[1..];
+ } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
+ op = .sub;
+ llvm_feat = decorated_llvm_feat[1..];
+ } else {
+ return error.InvalidLlvmCpuFeaturesFormat;
+ }
+ for (arch.allFeaturesList()) |feature, index| {
+ const this_llvm_name = feature.llvm_name orelse continue;
+ if (mem.eql(u8, llvm_feat, this_llvm_name)) {
+ switch (op) {
+ .add => set.addFeature(@intCast(u8, index)),
+ .sub => set.removeFeature(@intCast(u8, index)),
+ }
+ break;
+ }
+ }
+ }
+ return Target.CpuFeatures{ .features = set };
+}
+
// ABI warning
-export fn stage2_cmd_targets() c_int {
- @import("print_targets.zig").cmdTargets(
- std.heap.c_allocator,
- &[0][]u8{},
- &std.io.getStdOut().outStream().stream,
- ) catch |err| {
+export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int {
+ cmdTargets(zig_triple) catch |err| {
std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
return -1;
};
return 0;
}
+fn cmdTargets(zig_triple: [*:0]const u8) !void {
+ var target = try Target.parse(mem.toSliceConst(u8, zig_triple));
+ target.Cross.cpu_features = blk: {
+ const llvm = @import("llvm.zig");
+ const llvm_cpu_name = llvm.GetHostCPUName();
+ const llvm_cpu_features = llvm.GetNativeFeatures();
+ break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features);
+ };
+ return @import("print_targets.zig").cmdTargets(
+ std.heap.c_allocator,
+ &[0][]u8{},
+ &std.io.getStdOut().outStream().stream,
+ target,
+ );
+}
+
const Stage2CpuFeatures = struct {
allocator: *mem.Allocator,
cpu_features: Target.CpuFeatures,
@@ -588,49 +651,17 @@ const Stage2CpuFeatures = struct {
fn createFromLLVM(
allocator: *mem.Allocator,
zig_triple: [*:0]const u8,
- llvm_cpu_name_z: [*:0]const u8,
- llvm_cpu_features: [*:0]const u8,
+ llvm_cpu_name_z: ?[*:0]const u8,
+ llvm_cpu_features: ?[*:0]const u8,
) !*Self {
const target = try Target.parse(mem.toSliceConst(u8, zig_triple));
const arch = target.Cross.arch;
- const llvm_cpu_name = mem.toSliceConst(u8, llvm_cpu_name_z);
-
- for (arch.allCpus()) |cpu| {
- const this_llvm_name = cpu.llvm_name orelse continue;
- if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
- return createFromCpu(allocator, arch, cpu);
- }
- }
-
- var set = arch.baselineFeatures();
- var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
- while (it.next()) |decorated_llvm_feat| {
- var op: enum {
- add,
- sub,
- } = undefined;
- var llvm_feat: []const u8 = undefined;
- if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
- op = .add;
- llvm_feat = decorated_llvm_feat[1..];
- } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
- op = .sub;
- llvm_feat = decorated_llvm_feat[1..];
- } else {
- return error.InvalidLlvmCpuFeaturesFormat;
- }
- for (arch.allFeaturesList()) |feature, index| {
- const this_llvm_name = feature.llvm_name orelse continue;
- if (mem.eql(u8, llvm_feat, this_llvm_name)) {
- switch (op) {
- .add => set.addFeature(@intCast(u8, index)),
- .sub => set.removeFeature(@intCast(u8, index)),
- }
- break;
- }
- }
+ const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features);
+ switch (cpu_features) {
+ .baseline => return createBaseline(allocator),
+ .cpu => |cpu| return createFromCpu(allocator, arch, cpu),
+ .features => |features| return createFromCpuFeatures(allocator, arch, features),
}
- return createFromCpuFeatures(allocator, arch, set);
}
fn createFromCpu(allocator: *mem.Allocator, arch: Target.Arch, cpu: *const Target.Cpu) !*Self {
@@ -823,8 +854,8 @@ export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error {
export fn stage2_cpu_features_llvm(
result: **Stage2CpuFeatures,
zig_triple: [*:0]const u8,
- llvm_cpu_name: [*:0]const u8,
- llvm_cpu_features: [*:0]const u8,
+ llvm_cpu_name: ?[*:0]const u8,
+ llvm_cpu_features: ?[*:0]const u8,
) Error {
result.* = Stage2CpuFeatures.createFromLLVM(
std.heap.c_allocator,