improve zig targets

This commit is contained in:
Andrew Kelley 2020-01-20 13:40:25 -05:00
parent bf82929557
commit f3dd9bbdac
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
7 changed files with 135 additions and 67 deletions

View File

@ -1,12 +1,8 @@
Finish these thigns before merging teh branch
* it gets the wrong answers with `-target-feature -sse,-avx`
* zig targets
- use non-reflection based cpu detection?
* finish refactoring target/arch/*
* `zig builtin` integration
* move target details to better location
* +foo,-bar vs foo,bar
* baseline features
const riscv32_default_features: []*const std.target.Feature = &[_]*const std.target.Feature{
@ -38,5 +34,3 @@ const i386_default_features_freestanding: []*const std.target.Feature = &[_]*con
&std.target.x86.feature_slowUnalignedMem16,
&std.target.x86.feature_x87,
};

View File

@ -18,8 +18,8 @@ pub const ObjectFormat = std.Target.ObjectFormat;
/// Deprecated: use `std.Target.SubSystem`.
pub const SubSystem = std.Target.SubSystem;
/// Deprecated: use `std.Target.Cross.CpuFeatures`.
pub const CpuFeatures = std.Target.Cross.CpuFeatures;
/// Deprecated: use `std.Target.CpuFeatures`.
pub const CpuFeatures = std.Target.CpuFeatures;
/// Deprecated: use `std.Target.Cpu`.
pub const Cpu = std.Target.Cpu;

View File

@ -569,18 +569,18 @@ pub const Target = union(enum) {
os: Os,
abi: Abi,
cpu_features: CpuFeatures = .baseline,
};
pub const CpuFeatures = union(enum) {
/// The "default" set of CPU features for cross-compiling. A conservative set
/// of features that is expected to be supported on most available hardware.
baseline,
pub const CpuFeatures = union(enum) {
/// The "default" set of CPU features for cross-compiling. A conservative set
/// of features that is expected to be supported on most available hardware.
baseline,
/// Target one specific CPU.
cpu: *const Cpu,
/// Target one specific CPU.
cpu: *const Cpu,
/// Explicitly provide the entire CPU feature set.
features: Cpu.Feature.Set,
};
/// Explicitly provide the entire CPU feature set.
features: Cpu.Feature.Set,
};
pub const current = Target{
@ -594,8 +594,15 @@ pub const Target = union(enum) {
pub const stack_align = 16;
pub fn cpuFeatures(self: Target) []const *const Cpu.Feature {
return switch (self.cpu_features) {
pub fn getCpuFeatures(self: Target) CpuFeatures {
return switch (self) {
.Native => builtin.cpu_features,
.Cross => |cross| cross.cpu_features,
};
}
pub fn cpuFeaturesList(self: Target) []const *const Cpu.Feature {
return switch (self.getCpuFeatures()) {
.baseline => self.arch.baselineFeatures(),
.cpu => |cpu| cpu.features,
.features => |features| features,

View File

@ -79,7 +79,7 @@ pub fn main() !void {
} else if (mem.eql(u8, cmd, "libc")) {
return cmdLibC(allocator, cmd_args);
} else if (mem.eql(u8, cmd, "targets")) {
return cmdTargets(allocator, cmd_args);
return @import("print_targets.zig").cmdTargets(allocator, cmd_args, stdout);
} else if (mem.eql(u8, cmd, "version")) {
return cmdVersion(allocator, cmd_args);
} else if (mem.eql(u8, cmd, "zen")) {
@ -789,48 +789,6 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
}
}
// cmd:targets /////////////////////////////////////////////////////////////////////////////////////
pub fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
try stdout.write("Architectures:\n");
{
comptime var i: usize = 0;
inline while (i < @memberCount(builtin.Arch)) : (i += 1) {
comptime const arch_tag = @memberName(builtin.Arch, i);
// NOTE: Cannot use empty string, see #918.
comptime const native_str = if (comptime mem.eql(u8, arch_tag, @tagName(builtin.arch))) " (native)\n" else "\n";
try stdout.print(" {}{}", .{ arch_tag, native_str });
}
}
try stdout.write("\n");
try stdout.write("Operating Systems:\n");
{
comptime var i: usize = 0;
inline while (i < @memberCount(Target.Os)) : (i += 1) {
comptime const os_tag = @memberName(Target.Os, i);
// NOTE: Cannot use empty string, see #918.
comptime const native_str = if (comptime mem.eql(u8, os_tag, @tagName(builtin.os))) " (native)\n" else "\n";
try stdout.print(" {}{}", .{ os_tag, native_str });
}
}
try stdout.write("\n");
try stdout.write("C ABIs:\n");
{
comptime var i: usize = 0;
inline while (i < @memberCount(Target.Abi)) : (i += 1) {
comptime const abi_tag = @memberName(Target.Abi, i);
// NOTE: Cannot use empty string, see #918.
comptime const native_str = if (comptime mem.eql(u8, abi_tag, @tagName(builtin.abi))) " (native)\n" else "\n";
try stdout.print(" {}{}", .{ abi_tag, native_str });
}
}
}
fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {
try stdout.print("{}\n", .{std.mem.toSliceConst(u8, c.ZIG_VERSION_STRING)});
}

View File

@ -0,0 +1,101 @@
const std = @import("std");
const fs = std.fs;
const io = std.io;
const mem = std.mem;
const Allocator = mem.Allocator;
const Target = std.Target;
pub fn cmdTargets(
allocator: *Allocator,
args: []const []const u8,
stdout: *io.OutStream(fs.File.WriteError),
) !void {
const BOS = io.BufferedOutStream(fs.File.WriteError);
var bos = BOS.init(stdout);
var jws = std.json.WriteStream(BOS.Stream, 6).init(&bos.stream);
try jws.beginObject();
try jws.objectField("arch");
try jws.beginObject();
{
inline for (@typeInfo(Target.Arch).Union.fields) |field| {
try jws.objectField(field.name);
if (field.field_type == void) {
try jws.emitNull();
} else {
try jws.emitString(@typeName(field.field_type));
}
}
}
try jws.endObject();
try jws.objectField("subArch");
try jws.beginObject();
const sub_arch_list = [_]type{
Target.Arch.Arm32,
Target.Arch.Arm64,
Target.Arch.Kalimba,
Target.Arch.Mips,
};
inline for (sub_arch_list) |SubArch| {
try jws.objectField(@typeName(SubArch));
try jws.beginArray();
inline for (@typeInfo(SubArch).Enum.fields) |field| {
try jws.arrayElem();
try jws.emitString(field.name);
}
try jws.endArray();
}
try jws.endObject();
try jws.objectField("os");
try jws.beginArray();
{
comptime var i: usize = 0;
inline while (i < @memberCount(Target.Os)) : (i += 1) {
const os_tag = @memberName(Target.Os, i);
try jws.arrayElem();
try jws.emitString(os_tag);
}
}
try jws.endArray();
try jws.objectField("abi");
try jws.beginArray();
{
comptime var i: usize = 0;
inline while (i < @memberCount(Target.Abi)) : (i += 1) {
const abi_tag = @memberName(Target.Abi, i);
try jws.arrayElem();
try jws.emitString(abi_tag);
}
}
try jws.endArray();
try jws.objectField("native");
try jws.beginObject();
{
const triple = try Target.current.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.objectField("os");
try jws.emitString(@tagName(Target.current.getOs()));
try jws.objectField("abi");
try jws.emitString(@tagName(Target.current.getAbi()));
try jws.objectField("cpuName");
switch (Target.current.getCpuFeatures()) {
.baseline, .features => try jws.emitNull(),
.cpu => |cpu| try jws.emitString(cpu.name),
}
try jws.endObject();
try jws.endObject();
try bos.stream.writeByte('\n');
return bos.flush();
}

View File

@ -539,7 +539,11 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
// ABI warning
export fn stage2_cmd_targets() c_int {
self_hosted_main.cmdTargets(std.heap.c_allocator, &[0][]u8{}) catch |err| {
@import("print_targets.zig").cmdTargets(
std.heap.c_allocator,
&[0][]u8{},
&std.io.getStdOut().outStream().stream,
) catch |err| {
std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
return -1;
};
@ -548,7 +552,7 @@ export fn stage2_cmd_targets() c_int {
const Stage2CpuFeatures = struct {
allocator: *mem.Allocator,
cpu_features: Target.Cross.CpuFeatures,
cpu_features: Target.CpuFeatures,
llvm_cpu_name: ?[*:0]const u8,
llvm_features_str: ?[*:0]const u8,

View File

@ -22349,7 +22349,11 @@ static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIns
return ira->codegen->invalid_instruction;
}
assert(target->value->type->id == ZigTypeIdEnum);
if (target->value->type->id != ZigTypeIdEnum) {
ir_add_error(ira, target,
buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name)));
return ira->codegen->invalid_instruction;
}
if (target->value->type->data.enumeration.src_field_count == 1 &&
!target->value->type->data.enumeration.non_exhaustive) {