Merge pull request #4264 from ziglang/layneson-cpus_and_features

Add support for target details (CPUs and their supported features)
This commit is contained in:
Andrew Kelley 2020-01-26 09:57:25 -05:00 committed by GitHub
commit 96e5f476c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 15444 additions and 506 deletions

View File

@ -57,11 +57,11 @@ pub const Buffer = struct {
/// The caller owns the returned memory. The Buffer becomes null and
/// is safe to `deinit`.
pub fn toOwnedSlice(self: *Buffer) []u8 {
pub fn toOwnedSlice(self: *Buffer) [:0]u8 {
const allocator = self.list.allocator;
const result = allocator.shrink(self.list.items, self.len());
const result = self.list.toOwnedSlice();
self.* = initNull(allocator);
return result;
return result[0 .. result.len - 1 :0];
}
pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {

View File

@ -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(),
},
});
}
@ -1970,9 +1972,46 @@ pub const LibExeObjStep = struct {
switch (self.target) {
.Native => {},
.Cross => {
.Cross => |cross| {
try zig_args.append("-target");
try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
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(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(',');
}
}
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());
}
},
}

View File

@ -1,5 +1,8 @@
pub usingnamespace @import("builtin");
/// Deprecated: use `std.Target.Os`.
pub const Target = std.Target;
/// Deprecated: use `std.Target.Os`.
pub const Os = std.Target.Os;
@ -15,6 +18,12 @@ pub const ObjectFormat = std.Target.ObjectFormat;
/// Deprecated: use `std.Target.SubSystem`.
pub const SubSystem = std.Target.SubSystem;
/// Deprecated: use `std.Target.CpuFeatures`.
pub const CpuFeatures = std.Target.CpuFeatures;
/// Deprecated: use `std.Target.Cpu`.
pub const Cpu = std.Target.Cpu;
/// `explicit_subsystem` is missing when the subsystem is automatically detected,
/// so Zig standard library has the subsystem detection logic here. This should generally be
/// used rather than `explicit_subsystem`.

View File

@ -81,10 +81,20 @@ pub fn getSelfDebugInfo() !*DebugInfo {
}
}
fn wantTtyColor() bool {
fn detectTTYConfig() TTY.Config {
var bytes: [128]u8 = undefined;
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
return if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty();
if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| {
return .escape_codes;
} else |_| {
if (stderr_file.supportsAnsiEscapeCodes()) {
return .escape_codes;
} else if (builtin.os == .windows) {
return .windows_api;
} else {
return .no_color;
}
}
}
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
@ -99,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
return;
};
writeCurrentStackTrace(stderr, debug_info, wantTtyColor(), start_addr) catch |err| {
writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(), start_addr) catch |err| {
stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return;
return;
};
@ -118,16 +128,16 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
return;
};
const tty_color = wantTtyColor();
printSourceAtAddress(debug_info, stderr, ip, tty_color) catch return;
const tty_config = detectTTYConfig();
printSourceAtAddress(debug_info, stderr, ip, tty_config) catch return;
const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*;
printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_color) catch return;
printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_config) catch return;
var it = StackIterator{
.first_addr = null,
.fp = bp,
};
while (it.next()) |return_address| {
printSourceAtAddress(debug_info, stderr, return_address - 1, tty_color) catch return;
printSourceAtAddress(debug_info, stderr, return_address - 1, tty_config) catch return;
}
}
@ -191,7 +201,7 @@ pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
return;
};
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, wantTtyColor()) catch |err| {
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, detectTTYConfig()) catch |err| {
stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return;
return;
};
@ -264,7 +274,7 @@ pub fn writeStackTrace(
out_stream: var,
allocator: *mem.Allocator,
debug_info: *DebugInfo,
tty_color: bool,
tty_config: TTY.Config,
) !void {
if (builtin.strip_debug_info) return error.MissingDebugInfo;
var frame_index: usize = 0;
@ -275,7 +285,7 @@ pub fn writeStackTrace(
frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;
}) {
const return_address = stack_trace.instruction_addresses[frame_index];
try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color);
try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_config);
}
}
@ -319,20 +329,25 @@ pub const StackIterator = struct {
}
};
pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
pub fn writeCurrentStackTrace(
out_stream: var,
debug_info: *DebugInfo,
tty_config: TTY.Config,
start_addr: ?usize,
) !void {
if (builtin.os == .windows) {
return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr);
return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr);
}
var it = StackIterator.init(start_addr);
while (it.next()) |return_address| {
try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color);
try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_config);
}
}
pub fn writeCurrentStackTraceWindows(
out_stream: var,
debug_info: *DebugInfo,
tty_color: bool,
tty_config: TTY.Config,
start_addr: ?usize,
) !void {
var addr_buf: [1024]usize = undefined;
@ -345,23 +360,28 @@ pub fn writeCurrentStackTraceWindows(
return;
} else 0;
for (addrs[start_i..]) |addr| {
try printSourceAtAddress(debug_info, out_stream, addr, tty_color);
try printSourceAtAddress(debug_info, out_stream, addr, tty_config);
}
}
/// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented,
/// make this `noasync fn` and remove the individual noasync calls.
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
if (builtin.os == .windows) {
return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_color);
return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_config);
}
if (comptime std.Target.current.isDarwin()) {
return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color);
return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_config);
}
return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_color);
return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_config);
}
fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_address: usize, tty_color: bool) !void {
fn printSourceAtAddressWindows(
di: *DebugInfo,
out_stream: var,
relocated_address: usize,
tty_config: TTY.Config,
) !void {
const allocator = getDebugInfoAllocator();
const base_address = process.getBaseAddress();
const relative_address = relocated_address - base_address;
@ -379,7 +399,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
}
} else {
// we have no information to add to the address
return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_color, printLineFromFileAnyOs);
return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs);
};
const mod = &di.modules[mod_index];
@ -507,85 +527,81 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
relocated_address,
symbol_name,
obj_basename,
tty_color,
tty_config,
printLineFromFileAnyOs,
);
}
const TtyColor = enum {
Red,
Green,
Cyan,
White,
Dim,
Bold,
Reset,
pub const TTY = struct {
pub const Color = enum {
Red,
Green,
Cyan,
White,
Dim,
Bold,
Reset,
};
pub const Config = enum {
no_color,
escape_codes,
// TODO give this a payload of file handle
windows_api,
fn setColor(conf: Config, out_stream: var, color: Color) void {
switch (conf) {
.no_color => return,
.escape_codes => switch (color) {
.Red => out_stream.write(RED) catch return,
.Green => out_stream.write(GREEN) catch return,
.Cyan => out_stream.write(CYAN) catch return,
.White, .Bold => out_stream.write(WHITE) catch return,
.Dim => out_stream.write(DIM) catch return,
.Reset => out_stream.write(RESET) catch return,
},
.windows_api => if (builtin.os == .windows) {
const S = struct {
var attrs: windows.WORD = undefined;
var init_attrs = false;
};
if (!S.init_attrs) {
S.init_attrs = true;
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
// TODO handle error
_ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info);
S.attrs = info.wAttributes;
}
// TODO handle errors
switch (color) {
.Red => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {};
},
.Green => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {};
},
.Cyan => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
},
.White, .Bold => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
},
.Dim => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {};
},
.Reset => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {};
},
}
} else {
unreachable;
},
}
}
};
};
/// TODO this is a special case hack right now. clean it up and maybe make it part of std.fmt
fn setTtyColor(tty_color: TtyColor) void {
if (stderr_file.supportsAnsiEscapeCodes()) {
switch (tty_color) {
TtyColor.Red => {
stderr_file.write(RED) catch return;
},
TtyColor.Green => {
stderr_file.write(GREEN) catch return;
},
TtyColor.Cyan => {
stderr_file.write(CYAN) catch return;
},
TtyColor.White, TtyColor.Bold => {
stderr_file.write(WHITE) catch return;
},
TtyColor.Dim => {
stderr_file.write(DIM) catch return;
},
TtyColor.Reset => {
stderr_file.write(RESET) catch return;
},
}
return;
}
if (builtin.os == .windows) {
const S = struct {
var attrs: windows.WORD = undefined;
var init_attrs = false;
};
if (!S.init_attrs) {
S.init_attrs = true;
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
// TODO handle error
_ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info);
S.attrs = info.wAttributes;
}
// TODO handle errors
switch (tty_color) {
TtyColor.Red => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {};
},
TtyColor.Green => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {};
},
TtyColor.Cyan => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
},
TtyColor.White, TtyColor.Bold => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
},
TtyColor.Dim => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {};
},
TtyColor.Reset => {
_ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {};
},
}
}
}
fn populateModule(di: *DebugInfo, mod: *Module) !void {
if (mod.populated)
return;
@ -650,12 +666,12 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
return null;
}
fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
const base_addr = process.getBaseAddress();
const adjusted_addr = 0x100000000 + (address - base_addr);
const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse {
return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFileAnyOs);
return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);
};
const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx));
@ -676,13 +692,13 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt
address,
symbol_name,
compile_unit_name,
tty_color,
tty_config,
printLineFromFileAnyOs,
);
}
pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
return debug_info.printSourceAtAddress(out_stream, address, tty_color, printLineFromFileAnyOs);
pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
return debug_info.printSourceAtAddress(out_stream, address, tty_config, printLineFromFileAnyOs);
}
fn printLineInfo(
@ -691,10 +707,10 @@ fn printLineInfo(
address: usize,
symbol_name: []const u8,
compile_unit_name: []const u8,
tty_color: bool,
tty_config: TTY.Config,
comptime printLineFromFile: var,
) !void {
if (tty_color) setTtyColor(.White);
tty_config.setColor(out_stream, .White);
if (line_info) |*li| {
try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column });
@ -702,11 +718,11 @@ fn printLineInfo(
try out_stream.print("???:?:?", .{});
}
if (tty_color) setTtyColor(.Reset);
tty_config.setColor(out_stream, .Reset);
try out_stream.write(": ");
if (tty_color) setTtyColor(.Dim);
tty_config.setColor(out_stream, .Dim);
try out_stream.print("0x{x} in {} ({})", .{ address, symbol_name, compile_unit_name });
if (tty_color) setTtyColor(.Reset);
tty_config.setColor(out_stream, .Reset);
try out_stream.write("\n");
// Show the matching source code line if possible
@ -717,9 +733,9 @@ fn printLineInfo(
const space_needed = @intCast(usize, li.column - 1);
try out_stream.writeByteNTimes(' ', space_needed);
if (tty_color) setTtyColor(.Green);
tty_config.setColor(out_stream, .Green);
try out_stream.write("^");
if (tty_color) setTtyColor(.Reset);
tty_config.setColor(out_stream, .Reset);
}
try out_stream.write("\n");
} else |err| switch (err) {
@ -1167,11 +1183,11 @@ pub const DwarfInfo = struct {
self: *DwarfInfo,
out_stream: var,
address: usize,
tty_color: bool,
tty_config: TTY.Config,
comptime printLineFromFile: var,
) !void {
const compile_unit = self.findCompileUnit(address) catch {
return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFile);
return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFile);
};
const compile_unit_name = try compile_unit.die.getAttrString(self, DW.AT_name);
@ -1188,7 +1204,7 @@ pub const DwarfInfo = struct {
address,
symbol_name,
compile_unit_name,
tty_color,
tty_config,
printLineFromFile,
);
}

View File

@ -1135,6 +1135,11 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
size.* += bytes.len;
}
pub fn allocPrint0(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![:0]u8 {
const result = try allocPrint(allocator, fmt ++ "\x00", args);
return result[0 .. result.len - 1 :0];
}
test "bufPrintInt" {
var buffer: [100]u8 = undefined;
const buf = buffer[0..];

View File

@ -382,6 +382,10 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T {
}
test "fmt.parseFloat" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
const testing = std.testing;
const expect = testing.expect;
const expectEqual = testing.expectEqual;

View File

@ -547,6 +547,10 @@ fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime packing:
}
test "Serializer/Deserializer generic" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
try testSerializerDeserializer(builtin.Endian.Big, .Byte);
try testSerializerDeserializer(builtin.Endian.Little, .Byte);
try testSerializerDeserializer(builtin.Endian.Big, .Bit);

View File

@ -95,6 +95,10 @@ test "math.fabs64.special" {
}
test "math.fabs128.special" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
expect(math.isPositiveInf(fabs(math.inf(f128))));
expect(math.isPositiveInf(fabs(-math.inf(f128))));
expect(math.isNan(fabs(math.nan(f128))));

View File

@ -74,6 +74,10 @@ pub fn isNegativeInf(x: var) bool {
}
test "math.isInf" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
expect(!isInf(@as(f16, 0.0)));
expect(!isInf(@as(f16, -0.0)));
expect(!isInf(@as(f32, 0.0)));
@ -93,6 +97,10 @@ test "math.isInf" {
}
test "math.isPositiveInf" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
expect(!isPositiveInf(@as(f16, 0.0)));
expect(!isPositiveInf(@as(f16, -0.0)));
expect(!isPositiveInf(@as(f32, 0.0)));
@ -112,6 +120,10 @@ test "math.isPositiveInf" {
}
test "math.isNegativeInf" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
expect(!isNegativeInf(@as(f16, 0.0)));
expect(!isNegativeInf(@as(f16, -0.0)));
expect(!isNegativeInf(@as(f32, 0.0)));

View File

@ -16,6 +16,10 @@ pub fn isSignalNan(x: var) bool {
}
test "math.isNan" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
expect(isNan(math.nan(f16)));
expect(isNan(math.nan(f32)));
expect(isNan(math.nan(f64)));

View File

@ -556,3 +556,21 @@ pub fn refAllDecls(comptime T: type) void {
if (!builtin.is_test) return;
_ = declarations(T);
}
/// Returns a slice of pointers to public declarations of a namespace.
pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const Decl {
const S = struct {
fn declNameLessThan(lhs: *const Decl, rhs: *const Decl) bool {
return mem.lessThan(u8, lhs.name, rhs.name);
}
};
comptime {
const decls = declarations(Namespace);
var array: [decls.len]*const Decl = undefined;
for (decls) |decl, i| {
array[i] = &@field(Namespace, decl.name);
}
std.sort.sort(*const Decl, &array, S.declNameLessThan);
return &array;
}
}

View File

@ -211,7 +211,7 @@ pub fn initTLS() ?*elf.Phdr {
if (tls_phdr) |phdr| {
// If the cpu is arm-based, check if it supports the TLS register
if (builtin.arch == builtin.Arch.arm and at_hwcap & std.os.linux.HWCAP_TLS == 0) {
if (builtin.arch == .arm and at_hwcap & std.os.linux.HWCAP_TLS == 0) {
// If the CPU does not support TLS via a coprocessor register,
// a kernel helper function can be used instead on certain linux kernels.
// See linux/arch/arm/include/asm/tls.h and musl/src/thread/arm/__set_thread_area.c.

View File

@ -31,6 +31,10 @@ fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
}
test "addtf3" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// NaN + any = NaN
@ -71,6 +75,10 @@ fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
}
test "subtf3" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
// qNaN - any = qNaN
test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);

View File

@ -11,6 +11,10 @@ fn test__fixtfdi(a: f128, expected: i64) void {
}
test "fixtfdi" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
//warn("\n", .{});
test__fixtfdi(-math.f128_max, math.minInt(i64));

View File

@ -11,6 +11,10 @@ fn test__fixtfsi(a: f128, expected: i32) void {
}
test "fixtfsi" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
//warn("\n", .{});
test__fixtfsi(-math.f128_max, math.minInt(i32));

View File

@ -11,6 +11,10 @@ fn test__fixtfti(a: f128, expected: i128) void {
}
test "fixtfti" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
//warn("\n", .{});
test__fixtfti(-math.f128_max, math.minInt(i128));

View File

@ -7,6 +7,10 @@ fn test__fixunstfdi(a: f128, expected: u64) void {
}
test "fixunstfdi" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__fixunstfdi(0.0, 0);
test__fixunstfdi(0.5, 0);

View File

@ -9,6 +9,10 @@ fn test__fixunstfsi(a: f128, expected: u32) void {
const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
test "fixunstfsi" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__fixunstfsi(inf128, 0xffffffff);
test__fixunstfsi(0, 0x0);
test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);

View File

@ -9,6 +9,10 @@ fn test__fixunstfti(a: f128, expected: u128) void {
const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
test "fixunstfti" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__fixunstfti(inf128, 0xffffffffffffffffffffffffffffffff);
test__fixunstfti(0.0, 0);

View File

@ -7,6 +7,10 @@ fn test__floattitf(a: i128, expected: f128) void {
}
test "floattitf" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__floattitf(0, 0.0);
test__floattitf(1, 1.0);

View File

@ -7,6 +7,10 @@ fn test__floatuntitf(a: u128, expected: f128) void {
}
test "floatuntitf" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test__floatuntitf(0, 0.0);
test__floatuntitf(1, 1.0);

View File

@ -44,6 +44,10 @@ fn makeNaN128(rand: u64) f128 {
return float_result;
}
test "multf3" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
// qNaN * any = qNaN
test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);

View File

@ -151,6 +151,10 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
}
test "trunctfsf2" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
// qnan
test__trunctfsf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
// nan
@ -186,6 +190,10 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
}
test "trunctfdf2" {
if (@import("std").Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
// qnan
test__trunctfdf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
// nan

View File

@ -49,6 +49,22 @@ pub const Target = union(enum) {
other,
};
pub const aarch64 = @import("target/aarch64.zig");
pub const amdgpu = @import("target/amdgpu.zig");
pub const arm = @import("target/arm.zig");
pub const avr = @import("target/avr.zig");
pub const bpf = @import("target/bpf.zig");
pub const hexagon = @import("target/hexagon.zig");
pub const mips = @import("target/mips.zig");
pub const msp430 = @import("target/msp430.zig");
pub const nvptx = @import("target/nvptx.zig");
pub const powerpc = @import("target/powerpc.zig");
pub const riscv = @import("target/riscv.zig");
pub const sparc = @import("target/sparc.zig");
pub const systemz = @import("target/systemz.zig");
pub const wasm = @import("target/wasm.zig");
pub const x86 = @import("target/x86.zig");
pub const Arch = union(enum) {
arm: Arm32,
armeb: Arm32,
@ -107,12 +123,12 @@ pub const Target = union(enum) {
v8_3a,
v8_2a,
v8_1a,
v8,
v8a,
v8r,
v8m_baseline,
v8m_mainline,
v8_1m_mainline,
v7,
v7a,
v7em,
v7m,
v7s,
@ -128,8 +144,8 @@ pub const Target = union(enum) {
pub fn version(version: Arm32) comptime_int {
return switch (version) {
.v8_5a, .v8_4a, .v8_3a, .v8_2a, .v8_1a, .v8, .v8r, .v8m_baseline, .v8m_mainline, .v8_1m_mainline => 8,
.v7, .v7em, .v7m, .v7s, .v7k, .v7ve => 7,
.v8_5a, .v8_4a, .v8_3a, .v8_2a, .v8_1a, .v8a, .v8r, .v8m_baseline, .v8m_mainline, .v8_1m_mainline => 8,
.v7a, .v7em, .v7m, .v7s, .v7k, .v7ve => 7,
.v6, .v6m, .v6k, .v6t2 => 6,
.v5, .v5te => 5,
.v4t => 4,
@ -142,10 +158,7 @@ pub const Target = union(enum) {
v8_3a,
v8_2a,
v8_1a,
v8,
v8r,
v8m_baseline,
v8m_mainline,
v8a,
};
pub const Kalimba = enum {
v5,
@ -156,6 +169,54 @@ pub const Target = union(enum) {
r6,
};
pub fn subArchName(arch: Arch) ?[]const u8 {
return switch (arch) {
.arm, .armeb, .thumb, .thumbeb => |arm32| @tagName(arm32),
.aarch64, .aarch64_be, .aarch64_32 => |arm64| @tagName(arm64),
.kalimba => |kalimba| @tagName(kalimba),
else => return null,
};
}
pub fn subArchFeature(arch: Arch) ?Cpu.Feature.Set.Index {
return switch (arch) {
.arm, .armeb, .thumb, .thumbeb => |arm32| switch (arm32) {
.v8_5a => @enumToInt(arm.Feature.armv8_5_a),
.v8_4a => @enumToInt(arm.Feature.armv8_4_a),
.v8_3a => @enumToInt(arm.Feature.armv8_3_a),
.v8_2a => @enumToInt(arm.Feature.armv8_2_a),
.v8_1a => @enumToInt(arm.Feature.armv8_1_a),
.v8a => @enumToInt(arm.Feature.armv8_a),
.v8r => @enumToInt(arm.Feature.armv8_r),
.v8m_baseline => @enumToInt(arm.Feature.armv8_m_base),
.v8m_mainline => @enumToInt(arm.Feature.armv8_m_main),
.v8_1m_mainline => @enumToInt(arm.Feature.armv8_1_m_main),
.v7a => @enumToInt(arm.Feature.armv7_a),
.v7em => @enumToInt(arm.Feature.armv7e_m),
.v7m => @enumToInt(arm.Feature.armv7_m),
.v7s => @enumToInt(arm.Feature.armv7s),
.v7k => @enumToInt(arm.Feature.armv7k),
.v7ve => @enumToInt(arm.Feature.armv7ve),
.v6 => @enumToInt(arm.Feature.armv6),
.v6m => @enumToInt(arm.Feature.armv6_m),
.v6k => @enumToInt(arm.Feature.armv6k),
.v6t2 => @enumToInt(arm.Feature.armv6t2),
.v5 => @enumToInt(arm.Feature.armv5t),
.v5te => @enumToInt(arm.Feature.armv5te),
.v4t => @enumToInt(arm.Feature.armv4t),
},
.aarch64, .aarch64_be, .aarch64_32 => |arm64| switch (arm64) {
.v8_5a => @enumToInt(aarch64.Feature.v8_5a),
.v8_4a => @enumToInt(aarch64.Feature.v8_4a),
.v8_3a => @enumToInt(aarch64.Feature.v8_3a),
.v8_2a => @enumToInt(aarch64.Feature.v8_2a),
.v8_1a => @enumToInt(aarch64.Feature.v8_1a),
.v8a => @enumToInt(aarch64.Feature.v8a),
},
else => return null,
};
}
pub fn isARM(arch: Arch) bool {
return switch (arch) {
.arm, .armeb => true,
@ -184,6 +245,53 @@ pub const Target = union(enum) {
};
}
pub fn parseCpu(arch: Arch, cpu_name: []const u8) !*const Cpu {
for (arch.allCpus()) |cpu| {
if (mem.eql(u8, cpu_name, cpu.name)) {
return cpu;
}
}
return error.UnknownCpu;
}
/// Comma-separated list of features, with + or - in front of each feature. This
/// form represents a deviation from baseline CPU, which is provided as a parameter.
/// Extra commas are ignored.
pub fn parseCpuFeatureSet(arch: Arch, cpu: *const Cpu, features_text: []const u8) !Cpu.Feature.Set {
const all_features = arch.allFeaturesList();
var set = cpu.features;
var it = mem.tokenize(features_text, ",");
while (it.next()) |item_text| {
var feature_name: []const u8 = undefined;
var op: enum {
add,
sub,
} = undefined;
if (mem.startsWith(u8, item_text, "+")) {
op = .add;
feature_name = item_text[1..];
} else if (mem.startsWith(u8, item_text, "-")) {
op = .sub;
feature_name = item_text[1..];
} else {
return error.InvalidCpuFeatures;
}
for (all_features) |feature, index_usize| {
const index = @intCast(Cpu.Feature.Set.Index, index_usize);
if (mem.eql(u8, feature_name, feature.name)) {
switch (op) {
.add => set.addFeature(index),
.sub => set.removeFeature(index),
}
break;
}
} else {
return error.UnknownCpuFeature;
}
}
return set;
}
pub fn toElfMachine(arch: Arch) std.elf.EM {
return switch (arch) {
.avr => ._AVR,
@ -296,6 +404,109 @@ pub const Target = union(enum) {
=> .Big,
};
}
/// Returns a name that matches the lib/std/target/* directory name.
pub fn genericName(arch: Arch) []const u8 {
return switch (arch) {
.arm, .armeb, .thumb, .thumbeb => "arm",
.aarch64, .aarch64_be, .aarch64_32 => "aarch64",
.avr => "avr",
.bpfel, .bpfeb => "bpf",
.hexagon => "hexagon",
.mips, .mipsel, .mips64, .mips64el => "mips",
.msp430 => "msp430",
.powerpc, .powerpc64, .powerpc64le => "powerpc",
.amdgcn => "amdgpu",
.riscv32, .riscv64 => "riscv",
.sparc, .sparcv9, .sparcel => "sparc",
.s390x => "systemz",
.i386, .x86_64 => "x86",
.nvptx, .nvptx64 => "nvptx",
.wasm32, .wasm64 => "wasm",
else => @tagName(arch),
};
}
/// All CPU features Zig is aware of, sorted lexicographically by name.
pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
return switch (arch) {
.arm, .armeb, .thumb, .thumbeb => &arm.all_features,
.aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
.avr => &avr.all_features,
.bpfel, .bpfeb => &bpf.all_features,
.hexagon => &hexagon.all_features,
.mips, .mipsel, .mips64, .mips64el => &mips.all_features,
.msp430 => &msp430.all_features,
.powerpc, .powerpc64, .powerpc64le => &powerpc.all_features,
.amdgcn => &amdgpu.all_features,
.riscv32, .riscv64 => &riscv.all_features,
.sparc, .sparcv9, .sparcel => &sparc.all_features,
.s390x => &systemz.all_features,
.i386, .x86_64 => &x86.all_features,
.nvptx, .nvptx64 => &nvptx.all_features,
.wasm32, .wasm64 => &wasm.all_features,
else => &[0]Cpu.Feature{},
};
}
/// The "default" set of CPU features for cross-compiling. A conservative set
/// of features that is expected to be supported on most available hardware.
pub fn getBaselineCpuFeatures(arch: Arch) CpuFeatures {
const S = struct {
const generic_cpu = Cpu{
.name = "generic",
.llvm_name = null,
.features = Cpu.Feature.Set.empty,
};
};
const cpu = switch (arch) {
.arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
.aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
.avr => &avr.cpu.avr1,
.bpfel, .bpfeb => &bpf.cpu.generic,
.hexagon => &hexagon.cpu.generic,
.mips, .mipsel => &mips.cpu.mips32,
.mips64, .mips64el => &mips.cpu.mips64,
.msp430 => &msp430.cpu.generic,
.powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
.amdgcn => &amdgpu.cpu.generic,
.riscv32 => &riscv.cpu.baseline_rv32,
.riscv64 => &riscv.cpu.baseline_rv64,
.sparc, .sparcv9, .sparcel => &sparc.cpu.generic,
.s390x => &systemz.cpu.generic,
.i386 => &x86.cpu.pentium4,
.x86_64 => &x86.cpu.x86_64,
.nvptx, .nvptx64 => &nvptx.cpu.sm_20,
.wasm32, .wasm64 => &wasm.cpu.generic,
else => &S.generic_cpu,
};
return CpuFeatures.initFromCpu(arch, cpu);
}
/// All CPUs Zig is aware of, sorted lexicographically by name.
pub fn allCpus(arch: Arch) []const *const Cpu {
return switch (arch) {
.arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
.aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
.avr => avr.all_cpus,
.bpfel, .bpfeb => bpf.all_cpus,
.hexagon => hexagon.all_cpus,
.mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
.msp430 => msp430.all_cpus,
.powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
.amdgcn => amdgpu.all_cpus,
.riscv32, .riscv64 => riscv.all_cpus,
.sparc, .sparcv9, .sparcel => sparc.all_cpus,
.s390x => systemz.all_cpus,
.i386, .x86_64 => x86.all_cpus,
.nvptx, .nvptx64 => nvptx.all_cpus,
.wasm32, .wasm64 => wasm.all_cpus,
else => &[0]*const Cpu{},
};
}
};
pub const Abi = enum {
@ -323,6 +534,109 @@ pub const Target = union(enum) {
macabi,
};
pub const Cpu = struct {
name: []const u8,
llvm_name: ?[:0]const u8,
features: Feature.Set,
pub const Feature = struct {
/// The bit index into `Set`. Has a default value of `undefined` because the canonical
/// structures are populated via comptime logic.
index: Set.Index = undefined,
/// Has a default value of `undefined` because the canonical
/// structures are populated via comptime logic.
name: []const u8 = undefined,
/// If this corresponds to an LLVM-recognized feature, this will be populated;
/// otherwise null.
llvm_name: ?[:0]const u8,
/// Human-friendly UTF-8 text.
description: []const u8,
/// Sparse `Set` of features this depends on.
dependencies: Set,
/// A bit set of all the features.
pub const Set = struct {
ints: [usize_count]usize,
pub const needed_bit_count = 174;
pub const byte_count = (needed_bit_count + 7) / 8;
pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
pub const Index = std.math.Log2Int(@IntType(false, usize_count * @bitSizeOf(usize)));
pub const ShiftInt = std.math.Log2Int(usize);
pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
pub fn empty_workaround() Set {
return Set{ .ints = [1]usize{0} ** usize_count };
}
pub fn isEnabled(set: Set, arch_feature_index: Index) bool {
const usize_index = arch_feature_index / @bitSizeOf(usize);
const bit_index = @intCast(ShiftInt, arch_feature_index % @bitSizeOf(usize));
return (set.ints[usize_index] & (@as(usize, 1) << bit_index)) != 0;
}
/// Adds the specified feature but not its dependencies.
pub fn addFeature(set: *Set, arch_feature_index: Index) void {
const usize_index = arch_feature_index / @bitSizeOf(usize);
const bit_index = @intCast(ShiftInt, arch_feature_index % @bitSizeOf(usize));
set.ints[usize_index] |= @as(usize, 1) << bit_index;
}
/// Removes the specified feature but not its dependents.
pub fn removeFeature(set: *Set, arch_feature_index: Index) void {
const usize_index = arch_feature_index / @bitSizeOf(usize);
const bit_index = @intCast(ShiftInt, arch_feature_index % @bitSizeOf(usize));
set.ints[usize_index] &= ~(@as(usize, 1) << bit_index);
}
pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void {
var old = set.ints;
while (true) {
for (all_features_list) |feature, index_usize| {
const index = @intCast(Index, index_usize);
if (set.isEnabled(index)) {
set.ints = @as(@Vector(usize_count, usize), set.ints) |
@as(@Vector(usize_count, usize), feature.dependencies.ints);
}
}
const nothing_changed = mem.eql(usize, &old, &set.ints);
if (nothing_changed) return;
old = set.ints;
}
}
pub fn asBytes(set: *const Set) *const [byte_count]u8 {
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 feature_set_fns(comptime F: type) type {
return struct {
/// Populates only the feature bits specified.
pub fn featureSet(features: []const F) Set {
var x = Set.empty_workaround(); // TODO remove empty_workaround
for (features) |feature| {
x.addFeature(@enumToInt(feature));
}
return x;
}
pub fn featureSetHas(set: Set, feature: F) bool {
return set.isEnabled(@enumToInt(feature));
}
};
}
};
};
pub const ObjectFormat = enum {
unknown,
coff,
@ -346,6 +660,28 @@ pub const Target = union(enum) {
arch: Arch,
os: Os,
abi: Abi,
cpu_features: CpuFeatures,
};
pub const CpuFeatures = struct {
/// The CPU to target. It has a set of features
/// which are overridden with the `features` field.
cpu: *const Cpu,
/// Explicitly provide the entire CPU feature set.
features: Cpu.Feature.Set,
pub fn initFromCpu(arch: Arch, cpu: *const Cpu) CpuFeatures {
var features = cpu.features;
if (arch.subArchFeature()) |sub_arch_index| {
features.addFeature(sub_arch_index);
}
features.populateDependencies(arch.allFeaturesList());
return CpuFeatures{
.cpu = cpu,
.features = features,
};
}
};
pub const current = Target{
@ -353,11 +689,19 @@ pub const Target = union(enum) {
.arch = builtin.arch,
.os = builtin.os,
.abi = builtin.abi,
.cpu_features = builtin.cpu_features,
},
};
pub const stack_align = 16;
pub fn getCpuFeatures(self: Target) CpuFeatures {
return switch (self) {
.Native => builtin.cpu_features,
.Cross => |cross| cross.cpu_features,
};
}
pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
return std.fmt.allocPrint(allocator, "{}{}-{}-{}", .{
@tagName(self.getArch()),
@ -423,14 +767,18 @@ pub const Target = union(enum) {
});
}
/// TODO: Support CPU features here?
/// https://github.com/ziglang/zig/issues/4261
pub fn parse(text: []const u8) !Target {
var it = mem.separate(text, "-");
const arch_name = it.next() orelse return error.MissingArchitecture;
const os_name = it.next() orelse return error.MissingOperatingSystem;
const abi_name = it.next();
const arch = try parseArchSub(arch_name);
var cross = Cross{
.arch = try parseArchSub(arch_name),
.arch = arch,
.cpu_features = arch.getBaselineCpuFeatures(),
.os = try parseOs(os_name),
.abi = undefined,
};
@ -496,7 +844,7 @@ pub const Target = union(enum) {
pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
const info = @typeInfo(Arch);
inline for (info.Union.fields) |field| {
if (mem.eql(u8, text, field.name)) {
if (mem.startsWith(u8, text, field.name)) {
if (field.field_type == void) {
return @as(Arch, @field(Arch, field.name));
} else {
@ -816,3 +1164,15 @@ pub const Target = union(enum) {
return .unavailable;
}
};
test "parseCpuFeatureSet" {
const arch: Target.Arch = .x86_64;
const baseline = arch.getBaselineCpuFeatures();
const set = try arch.parseCpuFeatureSet(baseline.cpu, "-sse,-avx,-cx8");
std.testing.expect(!Target.x86.featureSetHas(set, .sse));
std.testing.expect(!Target.x86.featureSetHas(set, .avx));
std.testing.expect(!Target.x86.featureSetHas(set, .cx8));
// These are expected because they are part of the baseline
std.testing.expect(Target.x86.featureSetHas(set, .cmov));
std.testing.expect(Target.x86.featureSetHas(set, .fxsr));
}

1450
lib/std/target/aarch64.zig Normal file

File diff suppressed because it is too large Load Diff

1315
lib/std/target/amdgpu.zig Normal file

File diff suppressed because it is too large Load Diff

2333
lib/std/target/arm.zig Normal file

File diff suppressed because it is too large Load Diff

2380
lib/std/target/avr.zig Normal file

File diff suppressed because it is too large Load Diff

76
lib/std/target/bpf.zig Normal file
View File

@ -0,0 +1,76 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
alu32,
dummy,
dwarfris,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.alu32)] = .{
.llvm_name = "alu32",
.description = "Enable ALU32 instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dummy)] = .{
.llvm_name = "dummy",
.description = "unused feature",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dwarfris)] = .{
.llvm_name = "dwarfris",
.description = "Disable MCAsmInfo DwarfUsesRelocationsAcrossSections",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{}),
};
pub const probe = Cpu{
.name = "probe",
.llvm_name = "probe",
.features = featureSet(&[_]Feature{}),
};
pub const v1 = Cpu{
.name = "v1",
.llvm_name = "v1",
.features = featureSet(&[_]Feature{}),
};
pub const v2 = Cpu{
.name = "v2",
.llvm_name = "v2",
.features = featureSet(&[_]Feature{}),
};
pub const v3 = Cpu{
.name = "v3",
.llvm_name = "v3",
.features = featureSet(&[_]Feature{}),
};
};
/// All bpf CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.generic,
&cpu.probe,
&cpu.v1,
&cpu.v2,
&cpu.v3,
};

312
lib/std/target/hexagon.zig Normal file
View File

@ -0,0 +1,312 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
duplex,
hvx,
hvx_length128b,
hvx_length64b,
hvxv60,
hvxv62,
hvxv65,
hvxv66,
long_calls,
mem_noshuf,
memops,
noreturn_stack_elim,
nvj,
nvs,
packets,
reserved_r19,
small_data,
v5,
v55,
v60,
v62,
v65,
v66,
zreg,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.duplex)] = .{
.llvm_name = "duplex",
.description = "Enable generation of duplex instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hvx)] = .{
.llvm_name = "hvx",
.description = "Hexagon HVX instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hvx_length128b)] = .{
.llvm_name = "hvx-length128b",
.description = "Hexagon HVX 128B instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
}),
};
result[@enumToInt(Feature.hvx_length64b)] = .{
.llvm_name = "hvx-length64b",
.description = "Hexagon HVX 64B instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
}),
};
result[@enumToInt(Feature.hvxv60)] = .{
.llvm_name = "hvxv60",
.description = "Hexagon HVX instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
}),
};
result[@enumToInt(Feature.hvxv62)] = .{
.llvm_name = "hvxv62",
.description = "Hexagon HVX instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
.hvxv60,
}),
};
result[@enumToInt(Feature.hvxv65)] = .{
.llvm_name = "hvxv65",
.description = "Hexagon HVX instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
.hvxv60,
.hvxv62,
}),
};
result[@enumToInt(Feature.hvxv66)] = .{
.llvm_name = "hvxv66",
.description = "Hexagon HVX instructions",
.dependencies = featureSet(&[_]Feature{
.hvx,
.hvxv60,
.hvxv62,
.hvxv65,
.zreg,
}),
};
result[@enumToInt(Feature.long_calls)] = .{
.llvm_name = "long-calls",
.description = "Use constant-extended calls",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mem_noshuf)] = .{
.llvm_name = "mem_noshuf",
.description = "Supports mem_noshuf feature",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.memops)] = .{
.llvm_name = "memops",
.description = "Use memop instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.noreturn_stack_elim)] = .{
.llvm_name = "noreturn-stack-elim",
.description = "Eliminate stack allocation in a noreturn function when possible",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.nvj)] = .{
.llvm_name = "nvj",
.description = "Support for new-value jumps",
.dependencies = featureSet(&[_]Feature{
.packets,
}),
};
result[@enumToInt(Feature.nvs)] = .{
.llvm_name = "nvs",
.description = "Support for new-value stores",
.dependencies = featureSet(&[_]Feature{
.packets,
}),
};
result[@enumToInt(Feature.packets)] = .{
.llvm_name = "packets",
.description = "Support for instruction packets",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.reserved_r19)] = .{
.llvm_name = "reserved-r19",
.description = "Reserve register R19",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.small_data)] = .{
.llvm_name = "small-data",
.description = "Allow GP-relative addressing of global variables",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v5)] = .{
.llvm_name = "v5",
.description = "Enable Hexagon V5 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v55)] = .{
.llvm_name = "v55",
.description = "Enable Hexagon V55 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v60)] = .{
.llvm_name = "v60",
.description = "Enable Hexagon V60 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v62)] = .{
.llvm_name = "v62",
.description = "Enable Hexagon V62 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v65)] = .{
.llvm_name = "v65",
.description = "Enable Hexagon V65 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v66)] = .{
.llvm_name = "v66",
.description = "Enable Hexagon V66 architecture",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.zreg)] = .{
.llvm_name = "zreg",
.description = "Hexagon ZReg extension instructions",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{
.duplex,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
.v60,
}),
};
pub const hexagonv5 = Cpu{
.name = "hexagonv5",
.llvm_name = "hexagonv5",
.features = featureSet(&[_]Feature{
.duplex,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
}),
};
pub const hexagonv55 = Cpu{
.name = "hexagonv55",
.llvm_name = "hexagonv55",
.features = featureSet(&[_]Feature{
.duplex,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
}),
};
pub const hexagonv60 = Cpu{
.name = "hexagonv60",
.llvm_name = "hexagonv60",
.features = featureSet(&[_]Feature{
.duplex,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
.v60,
}),
};
pub const hexagonv62 = Cpu{
.name = "hexagonv62",
.llvm_name = "hexagonv62",
.features = featureSet(&[_]Feature{
.duplex,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
.v60,
.v62,
}),
};
pub const hexagonv65 = Cpu{
.name = "hexagonv65",
.llvm_name = "hexagonv65",
.features = featureSet(&[_]Feature{
.duplex,
.mem_noshuf,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
.v60,
.v62,
.v65,
}),
};
pub const hexagonv66 = Cpu{
.name = "hexagonv66",
.llvm_name = "hexagonv66",
.features = featureSet(&[_]Feature{
.duplex,
.mem_noshuf,
.memops,
.nvj,
.nvs,
.packets,
.small_data,
.v5,
.v55,
.v60,
.v62,
.v65,
.v66,
}),
};
};
/// All hexagon CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.generic,
&cpu.hexagonv5,
&cpu.hexagonv55,
&cpu.hexagonv60,
&cpu.hexagonv62,
&cpu.hexagonv65,
&cpu.hexagonv66,
};

518
lib/std/target/mips.zig Normal file
View File

@ -0,0 +1,518 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
abs2008,
cnmips,
crc,
dsp,
dspr2,
dspr3,
eva,
fp64,
fpxx,
ginv,
gp64,
long_calls,
micromips,
mips1,
mips16,
mips2,
mips3,
mips32,
mips32r2,
mips32r3,
mips32r5,
mips32r6,
mips3_32,
mips3_32r2,
mips4,
mips4_32,
mips4_32r2,
mips5,
mips5_32r2,
mips64,
mips64r2,
mips64r3,
mips64r5,
mips64r6,
msa,
mt,
nan2008,
noabicalls,
nomadd4,
nooddspreg,
p5600,
ptr64,
single_float,
soft_float,
sym32,
use_indirect_jump_hazard,
use_tcc_in_div,
vfpu,
virt,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.abs2008)] = .{
.llvm_name = "abs2008",
.description = "Disable IEEE 754-2008 abs.fmt mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.cnmips)] = .{
.llvm_name = "cnmips",
.description = "Octeon cnMIPS Support",
.dependencies = featureSet(&[_]Feature{
.mips64r2,
}),
};
result[@enumToInt(Feature.crc)] = .{
.llvm_name = "crc",
.description = "Mips R6 CRC ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dsp)] = .{
.llvm_name = "dsp",
.description = "Mips DSP ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dspr2)] = .{
.llvm_name = "dspr2",
.description = "Mips DSP-R2 ASE",
.dependencies = featureSet(&[_]Feature{
.dsp,
}),
};
result[@enumToInt(Feature.dspr3)] = .{
.llvm_name = "dspr3",
.description = "Mips DSP-R3 ASE",
.dependencies = featureSet(&[_]Feature{
.dsp,
.dspr2,
}),
};
result[@enumToInt(Feature.eva)] = .{
.llvm_name = "eva",
.description = "Mips EVA ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fp64)] = .{
.llvm_name = "fp64",
.description = "Support 64-bit FP registers",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fpxx)] = .{
.llvm_name = "fpxx",
.description = "Support for FPXX",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ginv)] = .{
.llvm_name = "ginv",
.description = "Mips Global Invalidate ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.gp64)] = .{
.llvm_name = "gp64",
.description = "General Purpose Registers are 64-bit wide",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.long_calls)] = .{
.llvm_name = "long-calls",
.description = "Disable use of the jal instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.micromips)] = .{
.llvm_name = "micromips",
.description = "microMips mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips1)] = .{
.llvm_name = "mips1",
.description = "Mips I ISA Support [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips16)] = .{
.llvm_name = "mips16",
.description = "Mips16 mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips2)] = .{
.llvm_name = "mips2",
.description = "Mips II ISA Support [highly experimental]",
.dependencies = featureSet(&[_]Feature{
.mips1,
}),
};
result[@enumToInt(Feature.mips3)] = .{
.llvm_name = "mips3",
.description = "MIPS III ISA Support [highly experimental]",
.dependencies = featureSet(&[_]Feature{
.fp64,
.gp64,
.mips2,
.mips3_32,
.mips3_32r2,
}),
};
result[@enumToInt(Feature.mips32)] = .{
.llvm_name = "mips32",
.description = "Mips32 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips2,
.mips3_32,
.mips4_32,
}),
};
result[@enumToInt(Feature.mips32r2)] = .{
.llvm_name = "mips32r2",
.description = "Mips32r2 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32,
.mips3_32r2,
.mips4_32r2,
.mips5_32r2,
}),
};
result[@enumToInt(Feature.mips32r3)] = .{
.llvm_name = "mips32r3",
.description = "Mips32r3 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32r2,
}),
};
result[@enumToInt(Feature.mips32r5)] = .{
.llvm_name = "mips32r5",
.description = "Mips32r5 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32r3,
}),
};
result[@enumToInt(Feature.mips32r6)] = .{
.llvm_name = "mips32r6",
.description = "Mips32r6 ISA Support [experimental]",
.dependencies = featureSet(&[_]Feature{
.abs2008,
.fp64,
.mips32r5,
.nan2008,
}),
};
result[@enumToInt(Feature.mips3_32)] = .{
.llvm_name = "mips3_32",
.description = "Subset of MIPS-III that is also in MIPS32 [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips3_32r2)] = .{
.llvm_name = "mips3_32r2",
.description = "Subset of MIPS-III that is also in MIPS32r2 [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips4)] = .{
.llvm_name = "mips4",
.description = "MIPS IV ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips3,
.mips4_32,
.mips4_32r2,
}),
};
result[@enumToInt(Feature.mips4_32)] = .{
.llvm_name = "mips4_32",
.description = "Subset of MIPS-IV that is also in MIPS32 [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips4_32r2)] = .{
.llvm_name = "mips4_32r2",
.description = "Subset of MIPS-IV that is also in MIPS32r2 [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips5)] = .{
.llvm_name = "mips5",
.description = "MIPS V ISA Support [highly experimental]",
.dependencies = featureSet(&[_]Feature{
.mips4,
.mips5_32r2,
}),
};
result[@enumToInt(Feature.mips5_32r2)] = .{
.llvm_name = "mips5_32r2",
.description = "Subset of MIPS-V that is also in MIPS32r2 [highly experimental]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mips64)] = .{
.llvm_name = "mips64",
.description = "Mips64 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32,
.mips5,
}),
};
result[@enumToInt(Feature.mips64r2)] = .{
.llvm_name = "mips64r2",
.description = "Mips64r2 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32r2,
.mips64,
}),
};
result[@enumToInt(Feature.mips64r3)] = .{
.llvm_name = "mips64r3",
.description = "Mips64r3 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32r3,
.mips64r2,
}),
};
result[@enumToInt(Feature.mips64r5)] = .{
.llvm_name = "mips64r5",
.description = "Mips64r5 ISA Support",
.dependencies = featureSet(&[_]Feature{
.mips32r5,
.mips64r3,
}),
};
result[@enumToInt(Feature.mips64r6)] = .{
.llvm_name = "mips64r6",
.description = "Mips64r6 ISA Support [experimental]",
.dependencies = featureSet(&[_]Feature{
.abs2008,
.mips32r6,
.mips64r5,
.nan2008,
}),
};
result[@enumToInt(Feature.msa)] = .{
.llvm_name = "msa",
.description = "Mips MSA ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mt)] = .{
.llvm_name = "mt",
.description = "Mips MT ASE",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.nan2008)] = .{
.llvm_name = "nan2008",
.description = "IEEE 754-2008 NaN encoding",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.noabicalls)] = .{
.llvm_name = "noabicalls",
.description = "Disable SVR4-style position-independent code",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.nomadd4)] = .{
.llvm_name = "nomadd4",
.description = "Disable 4-operand madd.fmt and related instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.nooddspreg)] = .{
.llvm_name = "nooddspreg",
.description = "Disable odd numbered single-precision registers",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.p5600)] = .{
.llvm_name = "p5600",
.description = "The P5600 Processor",
.dependencies = featureSet(&[_]Feature{
.mips32r5,
}),
};
result[@enumToInt(Feature.ptr64)] = .{
.llvm_name = "ptr64",
.description = "Pointers are 64-bit wide",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.single_float)] = .{
.llvm_name = "single-float",
.description = "Only supports single precision float",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.soft_float)] = .{
.llvm_name = "soft-float",
.description = "Does not support floating point instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sym32)] = .{
.llvm_name = "sym32",
.description = "Symbols are 32 bit on Mips64",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.use_indirect_jump_hazard)] = .{
.llvm_name = "use-indirect-jump-hazard",
.description = "Use indirect jump guards to prevent certain speculation based attacks",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.use_tcc_in_div)] = .{
.llvm_name = "use-tcc-in-div",
.description = "Force the assembler to use trapping",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vfpu)] = .{
.llvm_name = "vfpu",
.description = "Enable vector FPU instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.virt)] = .{
.llvm_name = "virt",
.description = "Mips Virtualization ASE",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const mips1 = Cpu{
.name = "mips1",
.llvm_name = "mips1",
.features = featureSet(&[_]Feature{
.mips1,
}),
};
pub const mips2 = Cpu{
.name = "mips2",
.llvm_name = "mips2",
.features = featureSet(&[_]Feature{
.mips2,
}),
};
pub const mips3 = Cpu{
.name = "mips3",
.llvm_name = "mips3",
.features = featureSet(&[_]Feature{
.mips3,
}),
};
pub const mips32 = Cpu{
.name = "mips32",
.llvm_name = "mips32",
.features = featureSet(&[_]Feature{
.mips32,
}),
};
pub const mips32r2 = Cpu{
.name = "mips32r2",
.llvm_name = "mips32r2",
.features = featureSet(&[_]Feature{
.mips32r2,
}),
};
pub const mips32r3 = Cpu{
.name = "mips32r3",
.llvm_name = "mips32r3",
.features = featureSet(&[_]Feature{
.mips32r3,
}),
};
pub const mips32r5 = Cpu{
.name = "mips32r5",
.llvm_name = "mips32r5",
.features = featureSet(&[_]Feature{
.mips32r5,
}),
};
pub const mips32r6 = Cpu{
.name = "mips32r6",
.llvm_name = "mips32r6",
.features = featureSet(&[_]Feature{
.mips32r6,
}),
};
pub const mips4 = Cpu{
.name = "mips4",
.llvm_name = "mips4",
.features = featureSet(&[_]Feature{
.mips4,
}),
};
pub const mips5 = Cpu{
.name = "mips5",
.llvm_name = "mips5",
.features = featureSet(&[_]Feature{
.mips5,
}),
};
pub const mips64 = Cpu{
.name = "mips64",
.llvm_name = "mips64",
.features = featureSet(&[_]Feature{
.mips64,
}),
};
pub const mips64r2 = Cpu{
.name = "mips64r2",
.llvm_name = "mips64r2",
.features = featureSet(&[_]Feature{
.mips64r2,
}),
};
pub const mips64r3 = Cpu{
.name = "mips64r3",
.llvm_name = "mips64r3",
.features = featureSet(&[_]Feature{
.mips64r3,
}),
};
pub const mips64r5 = Cpu{
.name = "mips64r5",
.llvm_name = "mips64r5",
.features = featureSet(&[_]Feature{
.mips64r5,
}),
};
pub const mips64r6 = Cpu{
.name = "mips64r6",
.llvm_name = "mips64r6",
.features = featureSet(&[_]Feature{
.mips64r6,
}),
};
pub const octeon = Cpu{
.name = "octeon",
.llvm_name = "octeon",
.features = featureSet(&[_]Feature{
.cnmips,
.mips64r2,
}),
};
pub const p5600 = Cpu{
.name = "p5600",
.llvm_name = "p5600",
.features = featureSet(&[_]Feature{
.p5600,
}),
};
};
/// All mips CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.mips1,
&cpu.mips2,
&cpu.mips3,
&cpu.mips32,
&cpu.mips32r2,
&cpu.mips32r3,
&cpu.mips32r5,
&cpu.mips32r6,
&cpu.mips4,
&cpu.mips5,
&cpu.mips64,
&cpu.mips64r2,
&cpu.mips64r3,
&cpu.mips64r5,
&cpu.mips64r6,
&cpu.octeon,
&cpu.p5600,
};

72
lib/std/target/msp430.zig Normal file
View File

@ -0,0 +1,72 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
ext,
hwmult16,
hwmult32,
hwmultf5,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.ext)] = .{
.llvm_name = "ext",
.description = "Enable MSP430-X extensions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hwmult16)] = .{
.llvm_name = "hwmult16",
.description = "Enable 16-bit hardware multiplier",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hwmult32)] = .{
.llvm_name = "hwmult32",
.description = "Enable 32-bit hardware multiplier",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hwmultf5)] = .{
.llvm_name = "hwmultf5",
.description = "Enable F5 series hardware multiplier",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{}),
};
pub const msp430 = Cpu{
.name = "msp430",
.llvm_name = "msp430",
.features = featureSet(&[_]Feature{}),
};
pub const msp430x = Cpu{
.name = "msp430x",
.llvm_name = "msp430x",
.features = featureSet(&[_]Feature{
.ext,
}),
};
};
/// All msp430 CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.generic,
&cpu.msp430,
&cpu.msp430x,
};

309
lib/std/target/nvptx.zig Normal file
View File

@ -0,0 +1,309 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
ptx32,
ptx40,
ptx41,
ptx42,
ptx43,
ptx50,
ptx60,
ptx61,
ptx63,
ptx64,
sm_20,
sm_21,
sm_30,
sm_32,
sm_35,
sm_37,
sm_50,
sm_52,
sm_53,
sm_60,
sm_61,
sm_62,
sm_70,
sm_72,
sm_75,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.ptx32)] = .{
.llvm_name = "ptx32",
.description = "Use PTX version 3.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx40)] = .{
.llvm_name = "ptx40",
.description = "Use PTX version 4.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx41)] = .{
.llvm_name = "ptx41",
.description = "Use PTX version 4.1",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx42)] = .{
.llvm_name = "ptx42",
.description = "Use PTX version 4.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx43)] = .{
.llvm_name = "ptx43",
.description = "Use PTX version 4.3",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx50)] = .{
.llvm_name = "ptx50",
.description = "Use PTX version 5.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx60)] = .{
.llvm_name = "ptx60",
.description = "Use PTX version 6.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx61)] = .{
.llvm_name = "ptx61",
.description = "Use PTX version 6.1",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx63)] = .{
.llvm_name = "ptx63",
.description = "Use PTX version 6.3",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ptx64)] = .{
.llvm_name = "ptx64",
.description = "Use PTX version 6.4",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_20)] = .{
.llvm_name = "sm_20",
.description = "Target SM 2.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_21)] = .{
.llvm_name = "sm_21",
.description = "Target SM 2.1",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_30)] = .{
.llvm_name = "sm_30",
.description = "Target SM 3.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_32)] = .{
.llvm_name = "sm_32",
.description = "Target SM 3.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_35)] = .{
.llvm_name = "sm_35",
.description = "Target SM 3.5",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_37)] = .{
.llvm_name = "sm_37",
.description = "Target SM 3.7",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_50)] = .{
.llvm_name = "sm_50",
.description = "Target SM 5.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_52)] = .{
.llvm_name = "sm_52",
.description = "Target SM 5.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_53)] = .{
.llvm_name = "sm_53",
.description = "Target SM 5.3",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_60)] = .{
.llvm_name = "sm_60",
.description = "Target SM 6.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_61)] = .{
.llvm_name = "sm_61",
.description = "Target SM 6.1",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_62)] = .{
.llvm_name = "sm_62",
.description = "Target SM 6.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_70)] = .{
.llvm_name = "sm_70",
.description = "Target SM 7.0",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_72)] = .{
.llvm_name = "sm_72",
.description = "Target SM 7.2",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sm_75)] = .{
.llvm_name = "sm_75",
.description = "Target SM 7.5",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const sm_20 = Cpu{
.name = "sm_20",
.llvm_name = "sm_20",
.features = featureSet(&[_]Feature{
.sm_20,
}),
};
pub const sm_21 = Cpu{
.name = "sm_21",
.llvm_name = "sm_21",
.features = featureSet(&[_]Feature{
.sm_21,
}),
};
pub const sm_30 = Cpu{
.name = "sm_30",
.llvm_name = "sm_30",
.features = featureSet(&[_]Feature{
.sm_30,
}),
};
pub const sm_32 = Cpu{
.name = "sm_32",
.llvm_name = "sm_32",
.features = featureSet(&[_]Feature{
.ptx40,
.sm_32,
}),
};
pub const sm_35 = Cpu{
.name = "sm_35",
.llvm_name = "sm_35",
.features = featureSet(&[_]Feature{
.sm_35,
}),
};
pub const sm_37 = Cpu{
.name = "sm_37",
.llvm_name = "sm_37",
.features = featureSet(&[_]Feature{
.ptx41,
.sm_37,
}),
};
pub const sm_50 = Cpu{
.name = "sm_50",
.llvm_name = "sm_50",
.features = featureSet(&[_]Feature{
.ptx40,
.sm_50,
}),
};
pub const sm_52 = Cpu{
.name = "sm_52",
.llvm_name = "sm_52",
.features = featureSet(&[_]Feature{
.ptx41,
.sm_52,
}),
};
pub const sm_53 = Cpu{
.name = "sm_53",
.llvm_name = "sm_53",
.features = featureSet(&[_]Feature{
.ptx42,
.sm_53,
}),
};
pub const sm_60 = Cpu{
.name = "sm_60",
.llvm_name = "sm_60",
.features = featureSet(&[_]Feature{
.ptx50,
.sm_60,
}),
};
pub const sm_61 = Cpu{
.name = "sm_61",
.llvm_name = "sm_61",
.features = featureSet(&[_]Feature{
.ptx50,
.sm_61,
}),
};
pub const sm_62 = Cpu{
.name = "sm_62",
.llvm_name = "sm_62",
.features = featureSet(&[_]Feature{
.ptx50,
.sm_62,
}),
};
pub const sm_70 = Cpu{
.name = "sm_70",
.llvm_name = "sm_70",
.features = featureSet(&[_]Feature{
.ptx60,
.sm_70,
}),
};
pub const sm_72 = Cpu{
.name = "sm_72",
.llvm_name = "sm_72",
.features = featureSet(&[_]Feature{
.ptx61,
.sm_72,
}),
};
pub const sm_75 = Cpu{
.name = "sm_75",
.llvm_name = "sm_75",
.features = featureSet(&[_]Feature{
.ptx63,
.sm_75,
}),
};
};
/// All nvptx CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.sm_20,
&cpu.sm_21,
&cpu.sm_30,
&cpu.sm_32,
&cpu.sm_35,
&cpu.sm_37,
&cpu.sm_50,
&cpu.sm_52,
&cpu.sm_53,
&cpu.sm_60,
&cpu.sm_61,
&cpu.sm_62,
&cpu.sm_70,
&cpu.sm_72,
&cpu.sm_75,
};

938
lib/std/target/powerpc.zig Normal file
View File

@ -0,0 +1,938 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
@"64bit",
@"64bitregs",
altivec,
booke,
bpermd,
cmpb,
crbits,
crypto,
direct_move,
e500,
extdiv,
fcpsgn,
float128,
fpcvt,
fprnd,
fpu,
fre,
fres,
frsqrte,
frsqrtes,
fsqrt,
hard_float,
htm,
icbt,
invariant_function_descriptors,
isa_v30_instructions,
isel,
ldbrx,
lfiwax,
longcall,
mfocrf,
msync,
partword_atomics,
popcntd,
power8_altivec,
power8_vector,
power9_altivec,
power9_vector,
ppc_postra_sched,
ppc_prera_sched,
ppc4xx,
ppc6xx,
qpx,
recipprec,
secure_plt,
slow_popcntd,
spe,
stfiwx,
two_const_nr,
vectors_use_two_units,
vsx,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.@"64bit")] = .{
.llvm_name = "64bit",
.description = "Enable 64-bit instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.@"64bitregs")] = .{
.llvm_name = "64bitregs",
.description = "Enable 64-bit registers usage for ppc32 [beta]",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.altivec)] = .{
.llvm_name = "altivec",
.description = "Enable Altivec instructions",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.booke)] = .{
.llvm_name = "booke",
.description = "Enable Book E instructions",
.dependencies = featureSet(&[_]Feature{
.icbt,
}),
};
result[@enumToInt(Feature.bpermd)] = .{
.llvm_name = "bpermd",
.description = "Enable the bpermd instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.cmpb)] = .{
.llvm_name = "cmpb",
.description = "Enable the cmpb instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.crbits)] = .{
.llvm_name = "crbits",
.description = "Use condition-register bits individually",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.crypto)] = .{
.llvm_name = "crypto",
.description = "Enable POWER8 Crypto instructions",
.dependencies = featureSet(&[_]Feature{
.power8_altivec,
}),
};
result[@enumToInt(Feature.direct_move)] = .{
.llvm_name = "direct-move",
.description = "Enable Power8 direct move instructions",
.dependencies = featureSet(&[_]Feature{
.vsx,
}),
};
result[@enumToInt(Feature.e500)] = .{
.llvm_name = "e500",
.description = "Enable E500/E500mc instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.extdiv)] = .{
.llvm_name = "extdiv",
.description = "Enable extended divide instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fcpsgn)] = .{
.llvm_name = "fcpsgn",
.description = "Enable the fcpsgn instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.float128)] = .{
.llvm_name = "float128",
.description = "Enable the __float128 data type for IEEE-754R Binary128.",
.dependencies = featureSet(&[_]Feature{
.vsx,
}),
};
result[@enumToInt(Feature.fpcvt)] = .{
.llvm_name = "fpcvt",
.description = "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.fprnd)] = .{
.llvm_name = "fprnd",
.description = "Enable the fri[mnpz] instructions",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.fpu)] = .{
.llvm_name = "fpu",
.description = "Enable classic FPU instructions",
.dependencies = featureSet(&[_]Feature{
.hard_float,
}),
};
result[@enumToInt(Feature.fre)] = .{
.llvm_name = "fre",
.description = "Enable the fre instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.fres)] = .{
.llvm_name = "fres",
.description = "Enable the fres instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.frsqrte)] = .{
.llvm_name = "frsqrte",
.description = "Enable the frsqrte instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.frsqrtes)] = .{
.llvm_name = "frsqrtes",
.description = "Enable the frsqrtes instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.fsqrt)] = .{
.llvm_name = "fsqrt",
.description = "Enable the fsqrt instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.hard_float)] = .{
.llvm_name = "hard-float",
.description = "Enable floating-point instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.htm)] = .{
.llvm_name = "htm",
.description = "Enable Hardware Transactional Memory instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.icbt)] = .{
.llvm_name = "icbt",
.description = "Enable icbt instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.invariant_function_descriptors)] = .{
.llvm_name = "invariant-function-descriptors",
.description = "Assume function descriptors are invariant",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.isa_v30_instructions)] = .{
.llvm_name = "isa-v30-instructions",
.description = "Enable instructions added in ISA 3.0.",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.isel)] = .{
.llvm_name = "isel",
.description = "Enable the isel instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ldbrx)] = .{
.llvm_name = "ldbrx",
.description = "Enable the ldbrx instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.lfiwax)] = .{
.llvm_name = "lfiwax",
.description = "Enable the lfiwax instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.longcall)] = .{
.llvm_name = "longcall",
.description = "Always use indirect calls",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mfocrf)] = .{
.llvm_name = "mfocrf",
.description = "Enable the MFOCRF instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.msync)] = .{
.llvm_name = "msync",
.description = "Has only the msync instruction instead of sync",
.dependencies = featureSet(&[_]Feature{
.booke,
}),
};
result[@enumToInt(Feature.partword_atomics)] = .{
.llvm_name = "partword-atomics",
.description = "Enable l[bh]arx and st[bh]cx.",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.popcntd)] = .{
.llvm_name = "popcntd",
.description = "Enable the popcnt[dw] instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.power8_altivec)] = .{
.llvm_name = "power8-altivec",
.description = "Enable POWER8 Altivec instructions",
.dependencies = featureSet(&[_]Feature{
.altivec,
}),
};
result[@enumToInt(Feature.power8_vector)] = .{
.llvm_name = "power8-vector",
.description = "Enable POWER8 vector instructions",
.dependencies = featureSet(&[_]Feature{
.power8_altivec,
.vsx,
}),
};
result[@enumToInt(Feature.power9_altivec)] = .{
.llvm_name = "power9-altivec",
.description = "Enable POWER9 Altivec instructions",
.dependencies = featureSet(&[_]Feature{
.isa_v30_instructions,
.power8_altivec,
}),
};
result[@enumToInt(Feature.power9_vector)] = .{
.llvm_name = "power9-vector",
.description = "Enable POWER9 vector instructions",
.dependencies = featureSet(&[_]Feature{
.isa_v30_instructions,
.power8_vector,
.power9_altivec,
}),
};
result[@enumToInt(Feature.ppc_postra_sched)] = .{
.llvm_name = "ppc-postra-sched",
.description = "Use PowerPC post-RA scheduling strategy",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ppc_prera_sched)] = .{
.llvm_name = "ppc-prera-sched",
.description = "Use PowerPC pre-RA scheduling strategy",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ppc4xx)] = .{
.llvm_name = "ppc4xx",
.description = "Enable PPC 4xx instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.ppc6xx)] = .{
.llvm_name = "ppc6xx",
.description = "Enable PPC 6xx instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.qpx)] = .{
.llvm_name = "qpx",
.description = "Enable QPX instructions",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.recipprec)] = .{
.llvm_name = "recipprec",
.description = "Assume higher precision reciprocal estimates",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.secure_plt)] = .{
.llvm_name = "secure-plt",
.description = "Enable secure plt mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.slow_popcntd)] = .{
.llvm_name = "slow-popcntd",
.description = "Has slow popcnt[dw] instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.spe)] = .{
.llvm_name = "spe",
.description = "Enable SPE instructions",
.dependencies = featureSet(&[_]Feature{
.hard_float,
}),
};
result[@enumToInt(Feature.stfiwx)] = .{
.llvm_name = "stfiwx",
.description = "Enable the stfiwx instruction",
.dependencies = featureSet(&[_]Feature{
.fpu,
}),
};
result[@enumToInt(Feature.two_const_nr)] = .{
.llvm_name = "two-const-nr",
.description = "Requires two constant Newton-Raphson computation",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vectors_use_two_units)] = .{
.llvm_name = "vectors-use-two-units",
.description = "Vectors use two units",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vsx)] = .{
.llvm_name = "vsx",
.description = "Enable VSX instructions",
.dependencies = featureSet(&[_]Feature{
.altivec,
}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const @"440" = Cpu{
.name = "440",
.llvm_name = "440",
.features = featureSet(&[_]Feature{
.booke,
.fres,
.frsqrte,
.icbt,
.isel,
.msync,
}),
};
pub const @"450" = Cpu{
.name = "450",
.llvm_name = "450",
.features = featureSet(&[_]Feature{
.booke,
.fres,
.frsqrte,
.icbt,
.isel,
.msync,
}),
};
pub const @"601" = Cpu{
.name = "601",
.llvm_name = "601",
.features = featureSet(&[_]Feature{
.fpu,
}),
};
pub const @"602" = Cpu{
.name = "602",
.llvm_name = "602",
.features = featureSet(&[_]Feature{
.fpu,
}),
};
pub const @"603" = Cpu{
.name = "603",
.llvm_name = "603",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"603e" = Cpu{
.name = "603e",
.llvm_name = "603e",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"603ev" = Cpu{
.name = "603ev",
.llvm_name = "603ev",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"604" = Cpu{
.name = "604",
.llvm_name = "604",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"604e" = Cpu{
.name = "604e",
.llvm_name = "604e",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"620" = Cpu{
.name = "620",
.llvm_name = "620",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"7400" = Cpu{
.name = "7400",
.llvm_name = "7400",
.features = featureSet(&[_]Feature{
.altivec,
.fres,
.frsqrte,
}),
};
pub const @"7450" = Cpu{
.name = "7450",
.llvm_name = "7450",
.features = featureSet(&[_]Feature{
.altivec,
.fres,
.frsqrte,
}),
};
pub const @"750" = Cpu{
.name = "750",
.llvm_name = "750",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const @"970" = Cpu{
.name = "970",
.llvm_name = "970",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fres,
.frsqrte,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const a2 = Cpu{
.name = "a2",
.llvm_name = "a2",
.features = featureSet(&[_]Feature{
.@"64bit",
.booke,
.cmpb,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.icbt,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.recipprec,
.slow_popcntd,
.stfiwx,
}),
};
pub const a2q = Cpu{
.name = "a2q",
.llvm_name = "a2q",
.features = featureSet(&[_]Feature{
.@"64bit",
.booke,
.cmpb,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.icbt,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.qpx,
.recipprec,
.slow_popcntd,
.stfiwx,
}),
};
pub const e500 = Cpu{
.name = "e500",
.llvm_name = "e500",
.features = featureSet(&[_]Feature{
.booke,
.icbt,
.isel,
}),
};
pub const e500mc = Cpu{
.name = "e500mc",
.llvm_name = "e500mc",
.features = featureSet(&[_]Feature{
.booke,
.icbt,
.isel,
.stfiwx,
}),
};
pub const e5500 = Cpu{
.name = "e5500",
.llvm_name = "e5500",
.features = featureSet(&[_]Feature{
.@"64bit",
.booke,
.icbt,
.isel,
.mfocrf,
.stfiwx,
}),
};
pub const g3 = Cpu{
.name = "g3",
.llvm_name = "g3",
.features = featureSet(&[_]Feature{
.fres,
.frsqrte,
}),
};
pub const g4 = Cpu{
.name = "g4",
.llvm_name = "g4",
.features = featureSet(&[_]Feature{
.altivec,
.fres,
.frsqrte,
}),
};
pub const @"g4+" = Cpu{
.name = "g4+",
.llvm_name = "g4+",
.features = featureSet(&[_]Feature{
.altivec,
.fres,
.frsqrte,
}),
};
pub const g5 = Cpu{
.name = "g5",
.llvm_name = "g5",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fres,
.frsqrte,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{
.hard_float,
}),
};
pub const ppc = Cpu{
.name = "ppc",
.llvm_name = "ppc",
.features = featureSet(&[_]Feature{
.hard_float,
}),
};
pub const ppc32 = Cpu{
.name = "ppc32",
.llvm_name = "ppc32",
.features = featureSet(&[_]Feature{
.hard_float,
}),
};
pub const ppc64 = Cpu{
.name = "ppc64",
.llvm_name = "ppc64",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fres,
.frsqrte,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const ppc64le = Cpu{
.name = "ppc64le",
.llvm_name = "ppc64le",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.bpermd,
.cmpb,
.crypto,
.direct_move,
.extdiv,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.htm,
.icbt,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.partword_atomics,
.popcntd,
.power8_altivec,
.power8_vector,
.recipprec,
.stfiwx,
.two_const_nr,
.vsx,
}),
};
pub const pwr3 = Cpu{
.name = "pwr3",
.llvm_name = "pwr3",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fres,
.frsqrte,
.mfocrf,
.stfiwx,
}),
};
pub const pwr4 = Cpu{
.name = "pwr4",
.llvm_name = "pwr4",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fres,
.frsqrte,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const pwr5 = Cpu{
.name = "pwr5",
.llvm_name = "pwr5",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const pwr5x = Cpu{
.name = "pwr5x",
.llvm_name = "pwr5x",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.mfocrf,
.stfiwx,
}),
};
pub const pwr6 = Cpu{
.name = "pwr6",
.llvm_name = "pwr6",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.cmpb,
.fcpsgn,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.lfiwax,
.mfocrf,
.recipprec,
.stfiwx,
}),
};
pub const pwr6x = Cpu{
.name = "pwr6x",
.llvm_name = "pwr6x",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.cmpb,
.fcpsgn,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.lfiwax,
.mfocrf,
.recipprec,
.stfiwx,
}),
};
pub const pwr7 = Cpu{
.name = "pwr7",
.llvm_name = "pwr7",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.bpermd,
.cmpb,
.extdiv,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.popcntd,
.recipprec,
.stfiwx,
.two_const_nr,
.vsx,
}),
};
pub const pwr8 = Cpu{
.name = "pwr8",
.llvm_name = "pwr8",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.bpermd,
.cmpb,
.crypto,
.direct_move,
.extdiv,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.htm,
.icbt,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.partword_atomics,
.popcntd,
.power8_altivec,
.power8_vector,
.recipprec,
.stfiwx,
.two_const_nr,
.vsx,
}),
};
pub const pwr9 = Cpu{
.name = "pwr9",
.llvm_name = "pwr9",
.features = featureSet(&[_]Feature{
.@"64bit",
.altivec,
.bpermd,
.cmpb,
.crypto,
.direct_move,
.extdiv,
.fcpsgn,
.fpcvt,
.fprnd,
.fre,
.fres,
.frsqrte,
.frsqrtes,
.fsqrt,
.htm,
.icbt,
.isa_v30_instructions,
.isel,
.ldbrx,
.lfiwax,
.mfocrf,
.partword_atomics,
.popcntd,
.power8_altivec,
.power8_vector,
.power9_altivec,
.power9_vector,
.ppc_postra_sched,
.ppc_prera_sched,
.recipprec,
.stfiwx,
.two_const_nr,
.vectors_use_two_units,
.vsx,
}),
};
};
/// All powerpc CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.@"440",
&cpu.@"450",
&cpu.@"601",
&cpu.@"602",
&cpu.@"603",
&cpu.@"603e",
&cpu.@"603ev",
&cpu.@"604",
&cpu.@"604e",
&cpu.@"620",
&cpu.@"7400",
&cpu.@"7450",
&cpu.@"750",
&cpu.@"970",
&cpu.a2,
&cpu.a2q,
&cpu.e500,
&cpu.e500mc,
&cpu.e5500,
&cpu.g3,
&cpu.g4,
&cpu.@"g4+",
&cpu.g5,
&cpu.generic,
&cpu.ppc,
&cpu.ppc32,
&cpu.ppc64,
&cpu.ppc64le,
&cpu.pwr3,
&cpu.pwr4,
&cpu.pwr5,
&cpu.pwr5x,
&cpu.pwr6,
&cpu.pwr6x,
&cpu.pwr7,
&cpu.pwr8,
&cpu.pwr9,
};

122
lib/std/target/riscv.zig Normal file
View File

@ -0,0 +1,122 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
@"64bit",
a,
c,
d,
e,
f,
m,
relax,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.@"64bit")] = .{
.llvm_name = "64bit",
.description = "Implements RV64",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.a)] = .{
.llvm_name = "a",
.description = "'A' (Atomic Instructions)",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.c)] = .{
.llvm_name = "c",
.description = "'C' (Compressed Instructions)",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.d)] = .{
.llvm_name = "d",
.description = "'D' (Double-Precision Floating-Point)",
.dependencies = featureSet(&[_]Feature{
.f,
}),
};
result[@enumToInt(Feature.e)] = .{
.llvm_name = "e",
.description = "Implements RV32E (provides 16 rather than 32 GPRs)",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.f)] = .{
.llvm_name = "f",
.description = "'F' (Single-Precision Floating-Point)",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.m)] = .{
.llvm_name = "m",
.description = "'M' (Integer Multiplication and Division)",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.relax)] = .{
.llvm_name = "relax",
.description = "Enable Linker relaxation.",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const baseline_rv32 = Cpu{
.name = "baseline_rv32",
.llvm_name = "generic-rv32",
.features = featureSet(&[_]Feature{
.a,
.c,
.d,
.f,
.m,
.relax,
}),
};
pub const baseline_rv64 = Cpu{
.name = "baseline_rv64",
.llvm_name = "generic-rv64",
.features = featureSet(&[_]Feature{
.@"64bit",
.a,
.c,
.d,
.f,
.m,
.relax,
}),
};
pub const generic_rv32 = Cpu{
.name = "generic_rv32",
.llvm_name = "generic-rv32",
.features = featureSet(&[_]Feature{}),
};
pub const generic_rv64 = Cpu{
.name = "generic_rv64",
.llvm_name = "generic-rv64",
.features = featureSet(&[_]Feature{
.@"64bit",
}),
};
};
/// All riscv CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.baseline_rv32,
&cpu.baseline_rv64,
&cpu.generic_rv32,
&cpu.generic_rv64,
};

495
lib/std/target/sparc.zig Normal file
View File

@ -0,0 +1,495 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
deprecated_v8,
detectroundchange,
fixallfdivsqrt,
hard_quad_float,
hasleoncasa,
hasumacsmac,
insertnopload,
leon,
leoncyclecounter,
leonpwrpsr,
no_fmuls,
no_fsmuld,
popc,
soft_float,
soft_mul_div,
v9,
vis,
vis2,
vis3,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.deprecated_v8)] = .{
.llvm_name = "deprecated-v8",
.description = "Enable deprecated V8 instructions in V9 mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.detectroundchange)] = .{
.llvm_name = "detectroundchange",
.description = "LEON3 erratum detection: Detects any rounding mode change request: use only the round-to-nearest rounding mode",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fixallfdivsqrt)] = .{
.llvm_name = "fixallfdivsqrt",
.description = "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hard_quad_float)] = .{
.llvm_name = "hard-quad-float",
.description = "Enable quad-word floating point instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hasleoncasa)] = .{
.llvm_name = "hasleoncasa",
.description = "Enable CASA instruction for LEON3 and LEON4 processors",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.hasumacsmac)] = .{
.llvm_name = "hasumacsmac",
.description = "Enable UMAC and SMAC for LEON3 and LEON4 processors",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.insertnopload)] = .{
.llvm_name = "insertnopload",
.description = "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.leon)] = .{
.llvm_name = "leon",
.description = "Enable LEON extensions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.leoncyclecounter)] = .{
.llvm_name = "leoncyclecounter",
.description = "Use the Leon cycle counter register",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.leonpwrpsr)] = .{
.llvm_name = "leonpwrpsr",
.description = "Enable the PWRPSR instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.no_fmuls)] = .{
.llvm_name = "no-fmuls",
.description = "Disable the fmuls instruction.",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.no_fsmuld)] = .{
.llvm_name = "no-fsmuld",
.description = "Disable the fsmuld instruction.",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.popc)] = .{
.llvm_name = "popc",
.description = "Use the popc (population count) instruction",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.soft_float)] = .{
.llvm_name = "soft-float",
.description = "Use software emulation for floating point",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.soft_mul_div)] = .{
.llvm_name = "soft-mul-div",
.description = "Use software emulation for integer multiply and divide",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.v9)] = .{
.llvm_name = "v9",
.description = "Enable SPARC-V9 instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vis)] = .{
.llvm_name = "vis",
.description = "Enable UltraSPARC Visual Instruction Set extensions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vis2)] = .{
.llvm_name = "vis2",
.description = "Enable Visual Instruction Set extensions II",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vis3)] = .{
.llvm_name = "vis3",
.description = "Enable Visual Instruction Set extensions III",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const at697e = Cpu{
.name = "at697e",
.llvm_name = "at697e",
.features = featureSet(&[_]Feature{
.insertnopload,
.leon,
}),
};
pub const at697f = Cpu{
.name = "at697f",
.llvm_name = "at697f",
.features = featureSet(&[_]Feature{
.insertnopload,
.leon,
}),
};
pub const f934 = Cpu{
.name = "f934",
.llvm_name = "f934",
.features = featureSet(&[_]Feature{}),
};
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{}),
};
pub const gr712rc = Cpu{
.name = "gr712rc",
.llvm_name = "gr712rc",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const gr740 = Cpu{
.name = "gr740",
.llvm_name = "gr740",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.hasumacsmac,
.leon,
.leoncyclecounter,
.leonpwrpsr,
}),
};
pub const hypersparc = Cpu{
.name = "hypersparc",
.llvm_name = "hypersparc",
.features = featureSet(&[_]Feature{}),
};
pub const leon2 = Cpu{
.name = "leon2",
.llvm_name = "leon2",
.features = featureSet(&[_]Feature{
.leon,
}),
};
pub const leon3 = Cpu{
.name = "leon3",
.llvm_name = "leon3",
.features = featureSet(&[_]Feature{
.hasumacsmac,
.leon,
}),
};
pub const leon4 = Cpu{
.name = "leon4",
.llvm_name = "leon4",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.hasumacsmac,
.leon,
}),
};
pub const ma2080 = Cpu{
.name = "ma2080",
.llvm_name = "ma2080",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2085 = Cpu{
.name = "ma2085",
.llvm_name = "ma2085",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2100 = Cpu{
.name = "ma2100",
.llvm_name = "ma2100",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2150 = Cpu{
.name = "ma2150",
.llvm_name = "ma2150",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2155 = Cpu{
.name = "ma2155",
.llvm_name = "ma2155",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2450 = Cpu{
.name = "ma2450",
.llvm_name = "ma2450",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2455 = Cpu{
.name = "ma2455",
.llvm_name = "ma2455",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2480 = Cpu{
.name = "ma2480",
.llvm_name = "ma2480",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2485 = Cpu{
.name = "ma2485",
.llvm_name = "ma2485",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2x5x = Cpu{
.name = "ma2x5x",
.llvm_name = "ma2x5x",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const ma2x8x = Cpu{
.name = "ma2x8x",
.llvm_name = "ma2x8x",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const myriad2 = Cpu{
.name = "myriad2",
.llvm_name = "myriad2",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const myriad2_1 = Cpu{
.name = "myriad2_1",
.llvm_name = "myriad2.1",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const myriad2_2 = Cpu{
.name = "myriad2_2",
.llvm_name = "myriad2.2",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const myriad2_3 = Cpu{
.name = "myriad2_3",
.llvm_name = "myriad2.3",
.features = featureSet(&[_]Feature{
.hasleoncasa,
.leon,
}),
};
pub const niagara = Cpu{
.name = "niagara",
.llvm_name = "niagara",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.v9,
.vis,
.vis2,
}),
};
pub const niagara2 = Cpu{
.name = "niagara2",
.llvm_name = "niagara2",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.popc,
.v9,
.vis,
.vis2,
}),
};
pub const niagara3 = Cpu{
.name = "niagara3",
.llvm_name = "niagara3",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.popc,
.v9,
.vis,
.vis2,
}),
};
pub const niagara4 = Cpu{
.name = "niagara4",
.llvm_name = "niagara4",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.popc,
.v9,
.vis,
.vis2,
.vis3,
}),
};
pub const sparclet = Cpu{
.name = "sparclet",
.llvm_name = "sparclet",
.features = featureSet(&[_]Feature{}),
};
pub const sparclite = Cpu{
.name = "sparclite",
.llvm_name = "sparclite",
.features = featureSet(&[_]Feature{}),
};
pub const sparclite86x = Cpu{
.name = "sparclite86x",
.llvm_name = "sparclite86x",
.features = featureSet(&[_]Feature{}),
};
pub const supersparc = Cpu{
.name = "supersparc",
.llvm_name = "supersparc",
.features = featureSet(&[_]Feature{}),
};
pub const tsc701 = Cpu{
.name = "tsc701",
.llvm_name = "tsc701",
.features = featureSet(&[_]Feature{}),
};
pub const ultrasparc = Cpu{
.name = "ultrasparc",
.llvm_name = "ultrasparc",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.v9,
.vis,
}),
};
pub const ultrasparc3 = Cpu{
.name = "ultrasparc3",
.llvm_name = "ultrasparc3",
.features = featureSet(&[_]Feature{
.deprecated_v8,
.v9,
.vis,
.vis2,
}),
};
pub const ut699 = Cpu{
.name = "ut699",
.llvm_name = "ut699",
.features = featureSet(&[_]Feature{
.fixallfdivsqrt,
.insertnopload,
.leon,
.no_fmuls,
.no_fsmuld,
}),
};
pub const v7 = Cpu{
.name = "v7",
.llvm_name = "v7",
.features = featureSet(&[_]Feature{
.no_fsmuld,
.soft_mul_div,
}),
};
pub const v8 = Cpu{
.name = "v8",
.llvm_name = "v8",
.features = featureSet(&[_]Feature{}),
};
pub const v9 = Cpu{
.name = "v9",
.llvm_name = "v9",
.features = featureSet(&[_]Feature{
.v9,
}),
};
};
/// All sparc CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.at697e,
&cpu.at697f,
&cpu.f934,
&cpu.generic,
&cpu.gr712rc,
&cpu.gr740,
&cpu.hypersparc,
&cpu.leon2,
&cpu.leon3,
&cpu.leon4,
&cpu.ma2080,
&cpu.ma2085,
&cpu.ma2100,
&cpu.ma2150,
&cpu.ma2155,
&cpu.ma2450,
&cpu.ma2455,
&cpu.ma2480,
&cpu.ma2485,
&cpu.ma2x5x,
&cpu.ma2x8x,
&cpu.myriad2,
&cpu.myriad2_1,
&cpu.myriad2_2,
&cpu.myriad2_3,
&cpu.niagara,
&cpu.niagara2,
&cpu.niagara3,
&cpu.niagara4,
&cpu.sparclet,
&cpu.sparclite,
&cpu.sparclite86x,
&cpu.supersparc,
&cpu.tsc701,
&cpu.ultrasparc,
&cpu.ultrasparc3,
&cpu.ut699,
&cpu.v7,
&cpu.v8,
&cpu.v9,
};

510
lib/std/target/systemz.zig Normal file
View File

@ -0,0 +1,510 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
deflate_conversion,
dfp_packed_conversion,
dfp_zoned_conversion,
distinct_ops,
enhanced_dat_2,
enhanced_sort,
execution_hint,
fast_serialization,
fp_extension,
guarded_storage,
high_word,
insert_reference_bits_multiple,
interlocked_access1,
load_and_trap,
load_and_zero_rightmost_byte,
load_store_on_cond,
load_store_on_cond_2,
message_security_assist_extension3,
message_security_assist_extension4,
message_security_assist_extension5,
message_security_assist_extension7,
message_security_assist_extension8,
message_security_assist_extension9,
miscellaneous_extensions,
miscellaneous_extensions_2,
miscellaneous_extensions_3,
population_count,
processor_assist,
reset_reference_bits_multiple,
transactional_execution,
vector,
vector_enhancements_1,
vector_enhancements_2,
vector_packed_decimal,
vector_packed_decimal_enhancement,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.deflate_conversion)] = .{
.llvm_name = "deflate-conversion",
.description = "Assume that the deflate-conversion facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dfp_packed_conversion)] = .{
.llvm_name = "dfp-packed-conversion",
.description = "Assume that the DFP packed-conversion facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.dfp_zoned_conversion)] = .{
.llvm_name = "dfp-zoned-conversion",
.description = "Assume that the DFP zoned-conversion facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.distinct_ops)] = .{
.llvm_name = "distinct-ops",
.description = "Assume that the distinct-operands facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.enhanced_dat_2)] = .{
.llvm_name = "enhanced-dat-2",
.description = "Assume that the enhanced-DAT facility 2 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.enhanced_sort)] = .{
.llvm_name = "enhanced-sort",
.description = "Assume that the enhanced-sort facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.execution_hint)] = .{
.llvm_name = "execution-hint",
.description = "Assume that the execution-hint facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fast_serialization)] = .{
.llvm_name = "fast-serialization",
.description = "Assume that the fast-serialization facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.fp_extension)] = .{
.llvm_name = "fp-extension",
.description = "Assume that the floating-point extension facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.guarded_storage)] = .{
.llvm_name = "guarded-storage",
.description = "Assume that the guarded-storage facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.high_word)] = .{
.llvm_name = "high-word",
.description = "Assume that the high-word facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.insert_reference_bits_multiple)] = .{
.llvm_name = "insert-reference-bits-multiple",
.description = "Assume that the insert-reference-bits-multiple facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.interlocked_access1)] = .{
.llvm_name = "interlocked-access1",
.description = "Assume that interlocked-access facility 1 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.load_and_trap)] = .{
.llvm_name = "load-and-trap",
.description = "Assume that the load-and-trap facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.load_and_zero_rightmost_byte)] = .{
.llvm_name = "load-and-zero-rightmost-byte",
.description = "Assume that the load-and-zero-rightmost-byte facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.load_store_on_cond)] = .{
.llvm_name = "load-store-on-cond",
.description = "Assume that the load/store-on-condition facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.load_store_on_cond_2)] = .{
.llvm_name = "load-store-on-cond-2",
.description = "Assume that the load/store-on-condition facility 2 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension3)] = .{
.llvm_name = "message-security-assist-extension3",
.description = "Assume that the message-security-assist extension facility 3 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension4)] = .{
.llvm_name = "message-security-assist-extension4",
.description = "Assume that the message-security-assist extension facility 4 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension5)] = .{
.llvm_name = "message-security-assist-extension5",
.description = "Assume that the message-security-assist extension facility 5 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension7)] = .{
.llvm_name = "message-security-assist-extension7",
.description = "Assume that the message-security-assist extension facility 7 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension8)] = .{
.llvm_name = "message-security-assist-extension8",
.description = "Assume that the message-security-assist extension facility 8 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.message_security_assist_extension9)] = .{
.llvm_name = "message-security-assist-extension9",
.description = "Assume that the message-security-assist extension facility 9 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.miscellaneous_extensions)] = .{
.llvm_name = "miscellaneous-extensions",
.description = "Assume that the miscellaneous-extensions facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.miscellaneous_extensions_2)] = .{
.llvm_name = "miscellaneous-extensions-2",
.description = "Assume that the miscellaneous-extensions facility 2 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.miscellaneous_extensions_3)] = .{
.llvm_name = "miscellaneous-extensions-3",
.description = "Assume that the miscellaneous-extensions facility 3 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.population_count)] = .{
.llvm_name = "population-count",
.description = "Assume that the population-count facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.processor_assist)] = .{
.llvm_name = "processor-assist",
.description = "Assume that the processor-assist facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.reset_reference_bits_multiple)] = .{
.llvm_name = "reset-reference-bits-multiple",
.description = "Assume that the reset-reference-bits-multiple facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.transactional_execution)] = .{
.llvm_name = "transactional-execution",
.description = "Assume that the transactional-execution facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vector)] = .{
.llvm_name = "vector",
.description = "Assume that the vectory facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vector_enhancements_1)] = .{
.llvm_name = "vector-enhancements-1",
.description = "Assume that the vector enhancements facility 1 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vector_enhancements_2)] = .{
.llvm_name = "vector-enhancements-2",
.description = "Assume that the vector enhancements facility 2 is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vector_packed_decimal)] = .{
.llvm_name = "vector-packed-decimal",
.description = "Assume that the vector packed decimal facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.vector_packed_decimal_enhancement)] = .{
.llvm_name = "vector-packed-decimal-enhancement",
.description = "Assume that the vector packed decimal enhancement facility is installed",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const arch10 = Cpu{
.name = "arch10",
.llvm_name = "arch10",
.features = featureSet(&[_]Feature{
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_and_trap,
.load_store_on_cond,
.message_security_assist_extension3,
.message_security_assist_extension4,
.miscellaneous_extensions,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
}),
};
pub const arch11 = Cpu{
.name = "arch11",
.llvm_name = "arch11",
.features = featureSet(&[_]Feature{
.dfp_packed_conversion,
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_and_trap,
.load_and_zero_rightmost_byte,
.load_store_on_cond,
.load_store_on_cond_2,
.message_security_assist_extension3,
.message_security_assist_extension4,
.message_security_assist_extension5,
.miscellaneous_extensions,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
.vector,
}),
};
pub const arch12 = Cpu{
.name = "arch12",
.llvm_name = "arch12",
.features = featureSet(&[_]Feature{
.dfp_packed_conversion,
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.guarded_storage,
.high_word,
.insert_reference_bits_multiple,
.interlocked_access1,
.load_and_trap,
.load_and_zero_rightmost_byte,
.load_store_on_cond,
.load_store_on_cond_2,
.message_security_assist_extension3,
.message_security_assist_extension4,
.message_security_assist_extension5,
.message_security_assist_extension7,
.message_security_assist_extension8,
.miscellaneous_extensions,
.miscellaneous_extensions_2,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
.vector,
.vector_enhancements_1,
.vector_packed_decimal,
}),
};
pub const arch13 = Cpu{
.name = "arch13",
.llvm_name = "arch13",
.features = featureSet(&[_]Feature{
.deflate_conversion,
.dfp_packed_conversion,
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.enhanced_sort,
.execution_hint,
.fast_serialization,
.fp_extension,
.guarded_storage,
.high_word,
.insert_reference_bits_multiple,
.interlocked_access1,
.load_and_trap,
.load_and_zero_rightmost_byte,
.load_store_on_cond,
.load_store_on_cond_2,
.message_security_assist_extension3,
.message_security_assist_extension4,
.message_security_assist_extension5,
.message_security_assist_extension7,
.message_security_assist_extension8,
.message_security_assist_extension9,
.miscellaneous_extensions,
.miscellaneous_extensions_2,
.miscellaneous_extensions_3,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
.vector,
.vector_enhancements_1,
.vector_enhancements_2,
.vector_packed_decimal,
.vector_packed_decimal_enhancement,
}),
};
pub const arch8 = Cpu{
.name = "arch8",
.llvm_name = "arch8",
.features = featureSet(&[_]Feature{}),
};
pub const arch9 = Cpu{
.name = "arch9",
.llvm_name = "arch9",
.features = featureSet(&[_]Feature{
.distinct_ops,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_store_on_cond,
.message_security_assist_extension3,
.message_security_assist_extension4,
.population_count,
.reset_reference_bits_multiple,
}),
};
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{}),
};
pub const z10 = Cpu{
.name = "z10",
.llvm_name = "z10",
.features = featureSet(&[_]Feature{}),
};
pub const z13 = Cpu{
.name = "z13",
.llvm_name = "z13",
.features = featureSet(&[_]Feature{
.dfp_packed_conversion,
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_and_trap,
.load_and_zero_rightmost_byte,
.load_store_on_cond,
.load_store_on_cond_2,
.message_security_assist_extension3,
.message_security_assist_extension4,
.message_security_assist_extension5,
.miscellaneous_extensions,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
.vector,
}),
};
pub const z14 = Cpu{
.name = "z14",
.llvm_name = "z14",
.features = featureSet(&[_]Feature{
.dfp_packed_conversion,
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.guarded_storage,
.high_word,
.insert_reference_bits_multiple,
.interlocked_access1,
.load_and_trap,
.load_and_zero_rightmost_byte,
.load_store_on_cond,
.load_store_on_cond_2,
.message_security_assist_extension3,
.message_security_assist_extension4,
.message_security_assist_extension5,
.message_security_assist_extension7,
.message_security_assist_extension8,
.miscellaneous_extensions,
.miscellaneous_extensions_2,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
.vector,
.vector_enhancements_1,
.vector_packed_decimal,
}),
};
pub const z196 = Cpu{
.name = "z196",
.llvm_name = "z196",
.features = featureSet(&[_]Feature{
.distinct_ops,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_store_on_cond,
.message_security_assist_extension3,
.message_security_assist_extension4,
.population_count,
.reset_reference_bits_multiple,
}),
};
pub const zEC12 = Cpu{
.name = "zEC12",
.llvm_name = "zEC12",
.features = featureSet(&[_]Feature{
.dfp_zoned_conversion,
.distinct_ops,
.enhanced_dat_2,
.execution_hint,
.fast_serialization,
.fp_extension,
.high_word,
.interlocked_access1,
.load_and_trap,
.load_store_on_cond,
.message_security_assist_extension3,
.message_security_assist_extension4,
.miscellaneous_extensions,
.population_count,
.processor_assist,
.reset_reference_bits_multiple,
.transactional_execution,
}),
};
};
/// All systemz CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.arch10,
&cpu.arch11,
&cpu.arch12,
&cpu.arch13,
&cpu.arch8,
&cpu.arch9,
&cpu.generic,
&cpu.z10,
&cpu.z13,
&cpu.z14,
&cpu.z196,
&cpu.zEC12,
};

114
lib/std/target/wasm.zig Normal file
View File

@ -0,0 +1,114 @@
const std = @import("../std.zig");
const Cpu = std.Target.Cpu;
pub const Feature = enum {
atomics,
bulk_memory,
exception_handling,
multivalue,
mutable_globals,
nontrapping_fptoint,
sign_ext,
simd128,
tail_call,
unimplemented_simd128,
};
pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
pub const all_features = blk: {
const len = @typeInfo(Feature).Enum.fields.len;
std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
var result: [len]Cpu.Feature = undefined;
result[@enumToInt(Feature.atomics)] = .{
.llvm_name = "atomics",
.description = "Enable Atomics",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.bulk_memory)] = .{
.llvm_name = "bulk-memory",
.description = "Enable bulk memory operations",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.exception_handling)] = .{
.llvm_name = "exception-handling",
.description = "Enable Wasm exception handling",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.multivalue)] = .{
.llvm_name = "multivalue",
.description = "Enable multivalue blocks, instructions, and functions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.mutable_globals)] = .{
.llvm_name = "mutable-globals",
.description = "Enable mutable globals",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.nontrapping_fptoint)] = .{
.llvm_name = "nontrapping-fptoint",
.description = "Enable non-trapping float-to-int conversion operators",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.sign_ext)] = .{
.llvm_name = "sign-ext",
.description = "Enable sign extension operators",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.simd128)] = .{
.llvm_name = "simd128",
.description = "Enable 128-bit SIMD",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.tail_call)] = .{
.llvm_name = "tail-call",
.description = "Enable tail call instructions",
.dependencies = featureSet(&[_]Feature{}),
};
result[@enumToInt(Feature.unimplemented_simd128)] = .{
.llvm_name = "unimplemented-simd128",
.description = "Enable 128-bit SIMD not yet implemented in engines",
.dependencies = featureSet(&[_]Feature{
.simd128,
}),
};
const ti = @typeInfo(Feature);
for (result) |*elem, i| {
elem.index = i;
elem.name = ti.Enum.fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const bleeding_edge = Cpu{
.name = "bleeding_edge",
.llvm_name = "bleeding-edge",
.features = featureSet(&[_]Feature{
.atomics,
.mutable_globals,
.nontrapping_fptoint,
.sign_ext,
.simd128,
}),
};
pub const generic = Cpu{
.name = "generic",
.llvm_name = "generic",
.features = featureSet(&[_]Feature{}),
};
pub const mvp = Cpu{
.name = "mvp",
.llvm_name = "mvp",
.features = featureSet(&[_]Feature{}),
};
};
/// All wasm CPUs, sorted alphabetically by name.
/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
/// compiler has inefficient memory and CPU usage, affecting build times.
pub const all_cpus = &[_]*const Cpu{
&cpu.bleeding_edge,
&cpu.generic,
&cpu.mvp,
};

2859
lib/std/target/x86.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,9 @@ 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);
// TODO figure out the current target rather than using the target that was specified when
// compiling the compiler
return @import("print_targets.zig").cmdTargets(allocator, cmd_args, stdout, Target.current);
} else if (mem.eql(u8, cmd, "version")) {
return cmdVersion(allocator, cmd_args);
} else if (mem.eql(u8, cmd, "zen")) {
@ -789,48 +791,6 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
}
}
// cmd:targets /////////////////////////////////////////////////////////////////////////////////////
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,251 @@
const std = @import("std");
const fs = std.fs;
const io = std.io;
const mem = std.mem;
const Allocator = mem.Allocator;
const Target = std.Target;
// TODO this is hard-coded until self-hosted gains this information canonically
const available_libcs = [_][]const u8{
"aarch64_be-linux-gnu",
"aarch64_be-linux-musl",
"aarch64_be-windows-gnu",
"aarch64-linux-gnu",
"aarch64-linux-musl",
"aarch64-windows-gnu",
"armeb-linux-gnueabi",
"armeb-linux-gnueabihf",
"armeb-linux-musleabi",
"armeb-linux-musleabihf",
"armeb-windows-gnu",
"arm-linux-gnueabi",
"arm-linux-gnueabihf",
"arm-linux-musleabi",
"arm-linux-musleabihf",
"arm-windows-gnu",
"i386-linux-gnu",
"i386-linux-musl",
"i386-windows-gnu",
"mips64el-linux-gnuabi64",
"mips64el-linux-gnuabin32",
"mips64el-linux-musl",
"mips64-linux-gnuabi64",
"mips64-linux-gnuabin32",
"mips64-linux-musl",
"mipsel-linux-gnu",
"mipsel-linux-musl",
"mips-linux-gnu",
"mips-linux-musl",
"powerpc64le-linux-gnu",
"powerpc64le-linux-musl",
"powerpc64-linux-gnu",
"powerpc64-linux-musl",
"powerpc-linux-gnu",
"powerpc-linux-musl",
"riscv64-linux-gnu",
"riscv64-linux-musl",
"s390x-linux-gnu",
"s390x-linux-musl",
"sparc-linux-gnu",
"sparcv9-linux-gnu",
"wasm32-freestanding-musl",
"x86_64-linux-gnu (native)",
"x86_64-linux-gnux32",
"x86_64-linux-musl",
"x86_64-windows-gnu",
};
// TODO this is hard-coded until self-hosted gains this information canonically
const available_glibcs = [_][]const u8{
"2.0",
"2.1",
"2.1.1",
"2.1.2",
"2.1.3",
"2.2",
"2.2.1",
"2.2.2",
"2.2.3",
"2.2.4",
"2.2.5",
"2.2.6",
"2.3",
"2.3.2",
"2.3.3",
"2.3.4",
"2.4",
"2.5",
"2.6",
"2.7",
"2.8",
"2.9",
"2.10",
"2.11",
"2.12",
"2.13",
"2.14",
"2.15",
"2.16",
"2.17",
"2.18",
"2.19",
"2.22",
"2.23",
"2.24",
"2.25",
"2.26",
"2.27",
"2.28",
"2.29",
"2.30",
};
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);
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();
inline for (@typeInfo(Target.Os).Enum.fields) |field| {
try jws.arrayElem();
try jws.emitString(field.name);
}
try jws.endArray();
try jws.objectField("abi");
try jws.beginArray();
inline for (@typeInfo(Target.Abi).Enum.fields) |field| {
try jws.arrayElem();
try jws.emitString(field.name);
}
try jws.endArray();
try jws.objectField("libc");
try jws.beginArray();
for (available_libcs) |libc| {
try jws.arrayElem();
try jws.emitString(libc);
}
try jws.endArray();
try jws.objectField("glibc");
try jws.beginArray();
for (available_glibcs) |glibc| {
try jws.arrayElem();
try jws.emitString(glibc);
}
try jws.endArray();
try jws.objectField("cpus");
try jws.beginObject();
inline for (@typeInfo(Target.Arch).Union.fields) |field| {
try jws.objectField(field.name);
try jws.beginObject();
const arch = @unionInit(Target.Arch, field.name, undefined);
for (arch.allCpus()) |cpu| {
try jws.objectField(cpu.name);
try jws.beginArray();
for (arch.allFeaturesList()) |feature, i| {
if (cpu.features.isEnabled(@intCast(u8, i))) {
try jws.arrayElem();
try jws.emitString(feature.name);
}
}
try jws.endArray();
}
try jws.endObject();
}
try jws.endObject();
try jws.objectField("cpuFeatures");
try jws.beginObject();
inline for (@typeInfo(Target.Arch).Union.fields) |field| {
try jws.objectField(field.name);
try jws.beginArray();
const arch = @unionInit(Target.Arch, field.name, undefined);
for (arch.allFeaturesList()) |feature| {
try jws.arrayElem();
try jws.emitString(feature.name);
}
try jws.endArray();
}
try jws.endObject();
try jws.objectField("native");
try jws.beginObject();
{
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(native_target.getArch()));
try jws.objectField("os");
try jws.emitString(@tagName(native_target.getOs()));
try jws.objectField("abi");
try jws.emitString(@tagName(native_target.getAbi()));
try jws.objectField("cpuName");
const cpu_features = native_target.getCpuFeatures();
try jws.emitString(cpu_features.cpu.name);
{
try jws.objectField("cpuFeatures");
try jws.beginArray();
for (native_target.getArch().allFeaturesList()) |feature, i_usize| {
const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
if (cpu_features.features.isEnabled(index)) {
try jws.arrayElem();
try jws.emitString(feature.name);
}
}
try jws.endArray();
}
// TODO implement native glibc version detection in self-hosted
try jws.endObject();
try jws.endObject();
try bos.stream.writeByte('\n');
return bos.flush();
}

View File

@ -9,9 +9,11 @@ const process = std.process;
const Allocator = mem.Allocator;
const ArrayList = std.ArrayList;
const Buffer = std.Buffer;
const Target = std.Target;
const self_hosted_main = @import("main.zig");
const errmsg = @import("errmsg.zig");
const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
const assert = std.debug.assert;
var stderr_file: fs.File = undefined;
var stderr: *io.OutStream(fs.File.WriteError) = undefined;
@ -63,6 +65,7 @@ const Error = extern enum {
CacheUnavailable,
PathTooLong,
CCompilerCannotFindFile,
NoCCompilerInstalled,
ReadingDepFile,
InvalidDepFile,
MissingArchitecture,
@ -80,6 +83,15 @@ const Error = extern enum {
OperationAborted,
BrokenPipe,
NoSpaceLeft,
NotLazy,
IsAsync,
ImportOutsidePkgPath,
UnknownCpu,
UnknownSubArchitecture,
UnknownCpuFeature,
InvalidCpuFeatures,
InvalidLlvmCpuFeaturesFormat,
UnknownApplicationBinaryInterface,
};
const FILE = std.c.FILE;
@ -149,7 +161,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
const argc_usize = @intCast(usize, argc);
var arg_i: usize = 0;
while (arg_i < argc_usize) : (arg_i += 1) {
try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));
try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
}
stdout = &std.io.getStdOut().outStream().stream;
@ -527,3 +539,294 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
node.activate();
node.context.maybeRefresh();
}
fn cpuFeaturesFromLLVM(
arch: Target.Arch,
llvm_cpu_name_z: ?[*:0]const u8,
llvm_cpu_features_opt: ?[*:0]const u8,
) !Target.CpuFeatures {
var result = arch.getBaselineCpuFeatures();
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)) {
// Here we use the non-dependencies-populated set,
// so that subtracting features later in this function
// affect the prepopulated set.
result = Target.CpuFeatures{
.cpu = cpu,
.features = cpu.features,
};
break;
}
}
}
const all_features = arch.allFeaturesList();
if (llvm_cpu_features_opt) |llvm_cpu_features| {
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 (all_features) |feature, index_usize| {
const this_llvm_name = feature.llvm_name orelse continue;
if (mem.eql(u8, llvm_feat, this_llvm_name)) {
const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
switch (op) {
.add => result.features.addFeature(index),
.sub => result.features.removeFeature(index),
}
break;
}
}
}
}
result.features.populateDependencies(all_features);
return result;
}
// ABI warning
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,
llvm_features_str: ?[*:0]const u8,
builtin_str: [:0]const u8,
cache_hash: [:0]const u8,
const Self = @This();
fn createFromNative(allocator: *mem.Allocator) !*Self {
const arch = Target.current.getArch();
const llvm = @import("llvm.zig");
const llvm_cpu_name = llvm.GetHostCPUName();
const llvm_cpu_features = llvm.GetNativeFeatures();
const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name, llvm_cpu_features);
return createFromCpuFeatures(allocator, arch, cpu_features);
}
fn createFromCpuFeatures(
allocator: *mem.Allocator,
arch: Target.Arch,
cpu_features: Target.CpuFeatures,
) !*Self {
const self = try allocator.create(Self);
errdefer allocator.destroy(self);
const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{
cpu_features.cpu.name,
cpu_features.features.asBytes(),
});
errdefer allocator.free(cache_hash);
const generic_arch_name = arch.genericName();
var builtin_str_buffer = try std.Buffer.allocPrint(allocator,
\\CpuFeatures{{
\\ .cpu = &Target.{}.cpu.{},
\\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
\\
, .{
generic_arch_name,
cpu_features.cpu.name,
generic_arch_name,
generic_arch_name,
});
defer builtin_str_buffer.deinit();
var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
defer llvm_features_buffer.deinit();
for (arch.allFeaturesList()) |feature, index_usize| {
const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
const is_enabled = cpu_features.features.isEnabled(index);
if (feature.llvm_name) |llvm_name| {
const plus_or_minus = "-+"[@boolToInt(is_enabled)];
try llvm_features_buffer.appendByte(plus_or_minus);
try llvm_features_buffer.append(llvm_name);
try llvm_features_buffer.append(",");
}
if (is_enabled) {
// TODO some kind of "zig identifier escape" function rather than
// unconditionally using @"" syntax
try builtin_str_buffer.append(" .@\"");
try builtin_str_buffer.append(feature.name);
try builtin_str_buffer.append("\",\n");
}
}
try builtin_str_buffer.append(
\\ }),
\\};
\\
);
assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
self.* = Self{
.allocator = allocator,
.cpu_features = cpu_features,
.llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr,
.builtin_str = builtin_str_buffer.toOwnedSlice(),
.cache_hash = cache_hash,
};
return self;
}
fn destroy(self: *Self) void {
self.allocator.free(self.cache_hash);
self.allocator.free(self.builtin_str);
// TODO if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str);
self.allocator.destroy(self);
}
};
// ABI warning
export fn stage2_cpu_features_parse(
result: **Stage2CpuFeatures,
zig_triple: ?[*:0]const u8,
cpu_name: ?[*:0]const u8,
cpu_features: ?[*:0]const u8,
) Error {
result.* = stage2ParseCpuFeatures(zig_triple, cpu_name, cpu_features) catch |err| switch (err) {
error.OutOfMemory => return .OutOfMemory,
error.UnknownArchitecture => return .UnknownArchitecture,
error.UnknownSubArchitecture => return .UnknownSubArchitecture,
error.UnknownOperatingSystem => return .UnknownOperatingSystem,
error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
error.MissingOperatingSystem => return .MissingOperatingSystem,
error.MissingArchitecture => return .MissingArchitecture,
error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
error.InvalidCpuFeatures => return .InvalidCpuFeatures,
};
return .None;
}
fn stage2ParseCpuFeatures(
zig_triple_oz: ?[*:0]const u8,
cpu_name_oz: ?[*:0]const u8,
cpu_features_oz: ?[*:0]const u8,
) !*Stage2CpuFeatures {
const zig_triple_z = zig_triple_oz orelse return Stage2CpuFeatures.createFromNative(std.heap.c_allocator);
const target = try Target.parse(mem.toSliceConst(u8, zig_triple_z));
const arch = target.Cross.arch;
const cpu = if (cpu_name_oz) |cpu_name_z| blk: {
const cpu_name = mem.toSliceConst(u8, cpu_name_z);
break :blk arch.parseCpu(cpu_name) catch |err| switch (err) {
error.UnknownCpu => {
std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
cpu_name,
@tagName(arch),
});
for (arch.allCpus()) |cpu| {
std.debug.warn(" {}\n", .{cpu.name});
}
process.exit(1);
},
else => |e| return e,
};
} else target.Cross.cpu_features.cpu;
var set = if (cpu_features_oz) |cpu_features_z| blk: {
const cpu_features = mem.toSliceConst(u8, cpu_features_z);
break :blk arch.parseCpuFeatureSet(cpu, cpu_features) catch |err| switch (err) {
error.UnknownCpuFeature => {
std.debug.warn(
\\Unknown CPU features specified.
\\Available CPU features for architecture '{}':
\\
, .{@tagName(arch)});
for (arch.allFeaturesList()) |feature| {
std.debug.warn(" {}\n", .{feature.name});
}
process.exit(1);
},
else => |e| return e,
};
} else cpu.features;
if (arch.subArchFeature()) |index| {
set.addFeature(index);
}
set.populateDependencies(arch.allFeaturesList());
return Stage2CpuFeatures.createFromCpuFeatures(std.heap.c_allocator, arch, .{
.cpu = cpu,
.features = set,
});
}
// ABI warning
export fn stage2_cpu_features_get_cache_hash(
cpu_features: *const Stage2CpuFeatures,
ptr: *[*:0]const u8,
len: *usize,
) void {
ptr.* = cpu_features.cache_hash.ptr;
len.* = cpu_features.cache_hash.len;
}
// ABI warning
export fn stage2_cpu_features_get_builtin_str(
cpu_features: *const Stage2CpuFeatures,
ptr: *[*:0]const u8,
len: *usize,
) void {
ptr.* = cpu_features.builtin_str.ptr;
len.* = cpu_features.builtin_str.len;
}
// ABI warning
export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
return if (cpu_features.cpu_features.cpu.llvm_name) |s| s.ptr else null;
}
// ABI warning
export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
return cpu_features.llvm_features_str;
}

View File

@ -2174,6 +2174,7 @@ struct CodeGen {
bool verbose_llvm_ir;
bool verbose_cimport;
bool verbose_cc;
bool verbose_llvm_cpu_features;
bool error_during_imports;
bool generate_error_name_table;
bool enable_cache; // mutually exclusive with output_dir

View File

@ -30,11 +30,6 @@ enum ResumeId {
ResumeIdCall,
};
// TODO https://github.com/ziglang/zig/issues/2883
// Until then we have this same default as Clang.
// This avoids https://github.com/ziglang/zig/issues/3275
static const char *riscv_default_features = "+a,+c,+d,+f,+m,+relax";
static void init_darwin_native(CodeGen *g) {
char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET");
char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET");
@ -8509,6 +8504,17 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
buf_appendf(contents, "pub const arch = %s;\n", cur_arch);
buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
{
buf_append_str(contents, "pub const cpu_features: CpuFeatures = ");
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len);
buf_append_mem(contents, ptr, len);
} else {
buf_append_str(contents, "arch.getBaselineCpuFeatures();\n");
}
}
if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {
buf_appendf(contents,
"pub const glibc_version: ?Version = Version{.major = %d, .minor = %d, .patch = %d};\n",
@ -8576,6 +8582,12 @@ static Error define_builtin_compile_vars(CodeGen *g) {
cache_int(&cache_hash, g->zig_target->vendor);
cache_int(&cache_hash, g->zig_target->os);
cache_int(&cache_hash, g->zig_target->abi);
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
cache_str(&cache_hash, ptr);
}
if (g->zig_target->glibc_version != nullptr) {
cache_int(&cache_hash, g->zig_target->glibc_version->major);
cache_int(&cache_hash, g->zig_target->glibc_version->minor);
@ -8700,37 +8712,25 @@ static void init(CodeGen *g) {
reloc_mode = LLVMRelocStatic;
}
const char *target_specific_cpu_args;
const char *target_specific_features;
const char *target_specific_cpu_args = "";
const char *target_specific_features = "";
if (g->zig_target->is_native) {
// LLVM creates invalid binaries on Windows sometimes.
// See https://github.com/ziglang/zig/issues/508
// As a workaround we do not use target native features on Windows.
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
target_specific_cpu_args = "";
target_specific_features = "";
} else {
target_specific_cpu_args = ZigLLVMGetHostCPUName();
target_specific_features = ZigLLVMGetNativeFeatures();
}
} else if (target_is_riscv(g->zig_target)) {
// TODO https://github.com/ziglang/zig/issues/2883
// Be aware of https://github.com/ziglang/zig/issues/3275
target_specific_cpu_args = "";
target_specific_features = riscv_default_features;
} else if (g->zig_target->arch == ZigLLVM_x86) {
// This is because we're really targeting i686 rather than i386.
// It's pretty much impossible to use many of the language features
// such as fp16 if you stick use the x87 only. This is also what clang
// uses as base cpu.
// TODO https://github.com/ziglang/zig/issues/2883
target_specific_cpu_args = "pentium4";
target_specific_features = (g->zig_target->os == OsFreestanding) ? "-sse": "";
} else {
target_specific_cpu_args = "";
target_specific_features = "";
target_specific_cpu_args = ZigLLVMGetHostCPUName();
target_specific_features = ZigLLVMGetNativeFeatures();
}
// Override CPU and features if defined by user.
if (g->zig_target->cpu_features != nullptr) {
target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
}
if (g->verbose_llvm_cpu_features) {
fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str));
fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args);
fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features);
}
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
LLVMCodeModelDefault, g->function_sections);
@ -9061,21 +9061,22 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
args.append("-target");
args.append(buf_ptr(&g->llvm_triple_str));
if (target_is_musl(g->zig_target) && target_is_riscv(g->zig_target)) {
// Musl depends on atomic instructions, which are disabled by default in Clang/LLVM's
// cross compilation CPU info for RISCV.
// TODO: https://github.com/ziglang/zig/issues/2883
const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
if (llvm_cpu != nullptr) {
args.append("-Xclang");
args.append("-target-cpu");
args.append("-Xclang");
args.append(llvm_cpu);
}
const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
if (llvm_target_features != nullptr) {
args.append("-Xclang");
args.append("-target-feature");
args.append("-Xclang");
args.append(riscv_default_features);
} else if (g->zig_target->os == OsFreestanding && g->zig_target->arch == ZigLLVM_x86) {
args.append("-Xclang");
args.append("-target-feature");
args.append("-Xclang");
args.append("-sse");
args.append(llvm_target_features);
}
}
if (g->zig_target->os == OsFreestanding) {
args.append("-ffreestanding");
}
@ -10270,6 +10271,12 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_int(ch, g->zig_target->vendor);
cache_int(ch, g->zig_target->os);
cache_int(ch, g->zig_target->abi);
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
cache_str(ch, ptr);
}
if (g->zig_target->glibc_version != nullptr) {
cache_int(ch, g->zig_target->glibc_version->major);
cache_int(ch, g->zig_target->glibc_version->minor);
@ -10610,6 +10617,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir;
child_gen->verbose_cimport = parent_gen->verbose_cimport;
child_gen->verbose_cc = parent_gen->verbose_cc;
child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features;
child_gen->llvm_argv = parent_gen->llvm_argv;
child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path;

View File

@ -58,6 +58,12 @@ const char *err_str(Error err) {
case ErrorNotLazy: return "not lazy";
case ErrorIsAsync: return "is async";
case ErrorImportOutsidePkgPath: return "import of file outside package path";
case ErrorUnknownCpu: return "unknown CPU";
case ErrorUnknownSubArchitecture: return "unknown sub-architecture";
case ErrorUnknownCpuFeature: return "unknown CPU feature";
case ErrorInvalidCpuFeatures: return "invalid CPU features";
case ErrorInvalidLlvmCpuFeaturesFormat: return "invalid LLVM CPU features format";
case ErrorUnknownApplicationBinaryInterface: return "unknown application binary interface";
}
return "(invalid error)";
}

View File

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

View File

@ -93,6 +93,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" --verbose-llvm-ir enable compiler debug output for LLVM IR\n"
" --verbose-cimport enable compiler debug output for C imports\n"
" --verbose-cc enable compiler debug output for C compilation\n"
" --verbose-llvm-cpu-features enable compiler debug output for LLVM CPU features\n"
" -dirafter [dir] add directory to AFTER include search path\n"
" -isystem [dir] add directory to SYSTEM include search path\n"
" -I[dir] add directory to include search path\n"
@ -100,6 +101,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" --override-lib-dir [arg] override path to Zig lib directory\n"
" -ffunction-sections places each function in a separate section\n"
" -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
" -target-cpu [cpu] target one specific CPU by name\n"
" -target-feature [features] specify the set of CPU features to target\n"
"\n"
"Link Options:\n"
" --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
@ -153,88 +156,6 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
return return_code;
}
static bool arch_available_in_llvm(ZigLLVM_ArchType arch) {
LLVMTargetRef target_ref;
char *err_msg = nullptr;
char triple_string[128];
sprintf(triple_string, "%s-unknown-unknown-unknown", ZigLLVMGetArchTypeName(arch));
return !LLVMGetTargetFromTriple(triple_string, &target_ref, &err_msg);
}
static int print_target_list(FILE *f) {
ZigTarget native;
get_native_target(&native);
fprintf(f, "Architectures:\n");
size_t arch_count = target_arch_count();
for (size_t arch_i = 0; arch_i < arch_count; arch_i += 1) {
ZigLLVM_ArchType arch = target_arch_enum(arch_i);
if (!arch_available_in_llvm(arch))
continue;
const char *arch_name = target_arch_name(arch);
SubArchList sub_arch_list = target_subarch_list(arch);
size_t sub_count = target_subarch_count(sub_arch_list);
const char *arch_native_str = (native.arch == arch) ? " (native)" : "";
fprintf(f, " %s%s\n", arch_name, arch_native_str);
for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
const char *sub_name = target_subarch_name(sub);
const char *sub_native_str = (native.arch == arch && native.sub_arch == sub) ? " (native)" : "";
fprintf(f, " %s%s\n", sub_name, sub_native_str);
}
}
fprintf(f, "\nOperating Systems:\n");
size_t os_count = target_os_count();
for (size_t i = 0; i < os_count; i += 1) {
Os os_type = target_os_enum(i);
const char *native_str = (native.os == os_type) ? " (native)" : "";
fprintf(f, " %s%s\n", target_os_name(os_type), native_str);
}
fprintf(f, "\nC ABIs:\n");
size_t abi_count = target_abi_count();
for (size_t i = 0; i < abi_count; i += 1) {
ZigLLVM_EnvironmentType abi = target_abi_enum(i);
const char *native_str = (native.abi == abi) ? " (native)" : "";
fprintf(f, " %s%s\n", target_abi_name(abi), native_str);
}
fprintf(f, "\nAvailable libcs:\n");
size_t libc_count = target_libc_count();
for (size_t i = 0; i < libc_count; i += 1) {
ZigTarget libc_target;
target_libc_enum(i, &libc_target);
bool is_native = native.arch == libc_target.arch &&
native.os == libc_target.os &&
native.abi == libc_target.abi;
const char *native_str = is_native ? " (native)" : "";
fprintf(f, " %s-%s-%s%s\n", target_arch_name(libc_target.arch),
target_os_name(libc_target.os), target_abi_name(libc_target.abi), native_str);
}
fprintf(f, "\nAvailable glibc versions:\n");
ZigGLibCAbi *glibc_abi;
Error err;
if ((err = glibc_load_metadata(&glibc_abi, get_zig_lib_dir(), true))) {
return EXIT_FAILURE;
}
for (size_t i = 0; i < glibc_abi->all_versions.length; i += 1) {
ZigGLibCVersion *this_ver = &glibc_abi->all_versions.at(i);
bool is_native = native.glibc_version != nullptr &&
native.glibc_version->major == this_ver->major &&
native.glibc_version->minor == this_ver->minor &&
native.glibc_version->patch == this_ver->patch;
const char *native_str = is_native ? " (native)" : "";
if (this_ver->patch == 0) {
fprintf(f, " %d.%d%s\n", this_ver->major, this_ver->minor, native_str);
} else {
fprintf(f, " %d.%d.%d%s\n", this_ver->major, this_ver->minor, this_ver->patch, native_str);
}
}
return EXIT_SUCCESS;
}
enum Cmd {
CmdNone,
CmdBuild,
@ -478,6 +399,7 @@ int main(int argc, char **argv) {
bool verbose_llvm_ir = false;
bool verbose_cimport = false;
bool verbose_cc = false;
bool verbose_llvm_cpu_features = false;
bool link_eh_frame_hdr = false;
ErrColor color = ErrColorAuto;
CacheOpt enable_cache = CacheOptAuto;
@ -528,6 +450,8 @@ int main(int argc, char **argv) {
WantStackCheck want_stack_check = WantStackCheckAuto;
WantCSanitize want_sanitize_c = WantCSanitizeAuto;
bool function_sections = false;
const char *cpu = nullptr;
const char *features = nullptr;
ZigList<const char *> llvm_argv = {0};
llvm_argv.append("zig (LLVM option parsing)");
@ -692,6 +616,8 @@ int main(int argc, char **argv) {
verbose_cimport = true;
} else if (strcmp(arg, "--verbose-cc") == 0) {
verbose_cc = true;
} else if (strcmp(arg, "--verbose-llvm-cpu-features") == 0) {
verbose_llvm_cpu_features = true;
} else if (strcmp(arg, "-rdynamic") == 0) {
rdynamic = true;
} else if (strcmp(arg, "--each-lib-rpath") == 0) {
@ -936,6 +862,10 @@ int main(int argc, char **argv) {
, argv[i]);
return EXIT_FAILURE;
}
} else if (strcmp(arg, "-target-cpu") == 0) {
cpu = argv[i];
} else if (strcmp(arg, "-target-feature") == 0) {
features = argv[i];
} else {
fprintf(stderr, "Invalid argument: %s\n", arg);
return print_error_usage(arg0);
@ -1051,15 +981,22 @@ int main(int argc, char **argv) {
}
}
Buf zig_triple_buf = BUF_INIT;
target_triple_zig(&zig_triple_buf, &target);
const char *stage2_triple_arg = target.is_native ? nullptr : buf_ptr(&zig_triple_buf);
if ((err = stage2_cpu_features_parse(&target.cpu_features, stage2_triple_arg, cpu, features))) {
fprintf(stderr, "unable to initialize CPU features: %s\n", err_str(err));
return main_exit(root_progress_node, EXIT_FAILURE);
}
if (output_dir != nullptr && enable_cache == CacheOptOn) {
fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");
return print_error_usage(arg0);
}
if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) {
Buf triple_buf = BUF_INIT;
target_triple_zig(&triple_buf, &target);
fprintf(stderr, "`--disable-pic` is incompatible with target '%s'\n", buf_ptr(&triple_buf));
fprintf(stderr, "`--disable-pic` is incompatible with target '%s'\n", buf_ptr(&zig_triple_buf));
return print_error_usage(arg0);
}
@ -1226,6 +1163,7 @@ int main(int argc, char **argv) {
g->verbose_llvm_ir = verbose_llvm_ir;
g->verbose_cimport = verbose_cimport;
g->verbose_cc = verbose_cc;
g->verbose_llvm_cpu_features = verbose_llvm_cpu_features;
g->output_dir = output_dir;
g->disable_gen_h = disable_gen_h;
g->bundle_compiler_rt = bundle_compiler_rt;
@ -1233,6 +1171,7 @@ int main(int argc, char **argv) {
g->system_linker_hack = system_linker_hack;
g->function_sections = function_sections;
for (size_t i = 0; i < lib_dirs.length; i += 1) {
codegen_add_lib_dir(g, lib_dirs.at(i));
}
@ -1413,7 +1352,7 @@ int main(int argc, char **argv) {
return main_exit(root_progress_node, EXIT_SUCCESS);
}
case CmdTargets:
return print_target_list(stdout);
return stage2_cmd_targets(buf_ptr(&zig_triple_buf));
case CmdNone:
return print_full_usage(arg0, stderr, EXIT_FAILURE);
}

View File

@ -57,9 +57,6 @@ static const ZigLLVM_SubArchType subarch_list_arm64[] = {
ZigLLVM_ARMSubArch_v8_2a,
ZigLLVM_ARMSubArch_v8_1a,
ZigLLVM_ARMSubArch_v8,
ZigLLVM_ARMSubArch_v8r,
ZigLLVM_ARMSubArch_v8m_baseline,
ZigLLVM_ARMSubArch_v8m_mainline,
};
static const ZigLLVM_SubArchType subarch_list_kalimba[] = {
@ -683,7 +680,7 @@ const char *target_subarch_name(ZigLLVM_SubArchType subarch) {
case ZigLLVM_ARMSubArch_v8_1a:
return "v8_1a";
case ZigLLVM_ARMSubArch_v8:
return "v8";
return "v8a";
case ZigLLVM_ARMSubArch_v8r:
return "v8r";
case ZigLLVM_ARMSubArch_v8m_baseline:
@ -693,7 +690,7 @@ const char *target_subarch_name(ZigLLVM_SubArchType subarch) {
case ZigLLVM_ARMSubArch_v8_1m_mainline:
return "v8_1m_mainline";
case ZigLLVM_ARMSubArch_v7:
return "v7";
return "v7a";
case ZigLLVM_ARMSubArch_v7em:
return "v7em";
case ZigLLVM_ARMSubArch_v7m:
@ -832,10 +829,10 @@ void init_all_targets(void) {
void target_triple_zig(Buf *triple, const ZigTarget *target) {
buf_resize(triple, 0);
buf_appendf(triple, "%s%s-%s-%s",
ZigLLVMGetArchTypeName(target->arch),
ZigLLVMGetSubArchTypeName(target->sub_arch),
ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
ZigLLVMGetEnvironmentTypeName(target->abi));
target_arch_name(target->arch),
target_subarch_name(target->sub_arch),
target_os_name(target->os),
target_abi_name(target->abi));
}
void target_triple_llvm(Buf *triple, const ZigTarget *target) {

View File

@ -91,6 +91,7 @@ struct ZigTarget {
Os os;
ZigLLVM_EnvironmentType abi;
ZigGLibCVersion *glibc_version; // null means default
Stage2CpuFeatures *cpu_features;
bool is_native;
};

View File

@ -2,7 +2,8 @@
// src-self-hosted/stage1.zig
#include "userland.h"
#include "ast_render.hpp"
#include "util.hpp"
#include "zig_llvm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -88,3 +89,58 @@ void stage2_progress_end(Stage2ProgressNode *node) {}
void stage2_progress_complete_one(Stage2ProgressNode *node) {}
void stage2_progress_disable_tty(Stage2Progress *progress) {}
void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
struct Stage2CpuFeatures {
const char *llvm_cpu_name;
const char *llvm_cpu_features;
const char *builtin_str;
const char *cache_hash;
};
Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_triple,
const char *cpu_name, const char *cpu_features)
{
if (zig_triple == nullptr) {
Stage2CpuFeatures *result = allocate<Stage2CpuFeatures>(1, "Stage2CpuFeatures");
result->llvm_cpu_name = ZigLLVMGetHostCPUName();
result->llvm_cpu_features = ZigLLVMGetNativeFeatures();
result->builtin_str = "arch.getBaselineCpuFeatures();\n";
result->cache_hash = "native\n\n";
*out = result;
return ErrorNone;
}
if (cpu_name == nullptr && cpu_features == nullptr) {
Stage2CpuFeatures *result = allocate<Stage2CpuFeatures>(1, "Stage2CpuFeatures");
result->builtin_str = "arch.getBaselineCpuFeatures();\n";
result->cache_hash = "\n\n";
*out = result;
return ErrorNone;
}
const char *msg = "stage0 called stage2_cpu_features_parse with non-null cpu name or features";
stage2_panic(msg, strlen(msg));
}
void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features,
const char **ptr, size_t *len)
{
*ptr = cpu_features->cache_hash;
*len = strlen(cpu_features->cache_hash);
}
const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) {
return cpu_features->llvm_cpu_name;
}
const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) {
return cpu_features->llvm_cpu_features;
}
void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features,
const char **ptr, size_t *len)
{
*ptr = cpu_features->builtin_str;
*len = strlen(cpu_features->builtin_str);
}
int stage2_cmd_targets(const char *zig_triple) {
const char *msg = "stage0 called stage2_cmd_targets";
stage2_panic(msg, strlen(msg));
}

View File

@ -78,6 +78,12 @@ enum Error {
ErrorNotLazy,
ErrorIsAsync,
ErrorImportOutsidePkgPath,
ErrorUnknownCpu,
ErrorUnknownSubArchitecture,
ErrorUnknownCpuFeature,
ErrorInvalidCpuFeatures,
ErrorInvalidLlvmCpuFeaturesFormat,
ErrorUnknownApplicationBinaryInterface,
};
// ABI warning
@ -174,4 +180,29 @@ ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
size_t completed_count, size_t estimated_total_items);
// ABI warning
struct Stage2CpuFeatures;
// ABI warning
ZIG_EXTERN_C Error stage2_cpu_features_parse(struct Stage2CpuFeatures **result,
const char *zig_triple, const char *cpu_name, const char *cpu_features);
// ABI warning
ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const struct Stage2CpuFeatures *cpu_features);
// ABI warning
ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const struct Stage2CpuFeatures *cpu_features);
// ABI warning
ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const struct Stage2CpuFeatures *cpu_features,
const char **ptr, size_t *len);
// ABI warning
ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatures *cpu_features,
const char **ptr, size_t *len);
// ABI warning
ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
#endif

View File

@ -821,7 +821,7 @@ const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
case ZigLLVM_ARMSubArch_v8_1a:
return "v8.1a";
case ZigLLVM_ARMSubArch_v8:
return "v8";
return "v8a";
case ZigLLVM_ARMSubArch_v8r:
return "v8r";
case ZigLLVM_ARMSubArch_v8m_baseline:
@ -831,7 +831,7 @@ const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
case ZigLLVM_ARMSubArch_v8_1m_mainline:
return "v8.1m.main";
case ZigLLVM_ARMSubArch_v7:
return "v7";
return "v7a";
case ZigLLVM_ARMSubArch_v7em:
return "v7em";
case ZigLLVM_ARMSubArch_v7m:

View File

@ -1,5 +1,6 @@
const tests = @import("tests.zig");
const builtin = @import("builtin");
const Target = @import("std").Target;
pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.addTest("non-exhaustive enums",
@ -272,9 +273,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
, &[_][]const u8{
"tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack",
});
tc.target = tests.Target{
.Cross = tests.CrossTarget{
tc.target = Target{
.Cross = .{
.arch = .wasm32,
.cpu_features = Target.Arch.wasm32.getBaselineCpuFeatures(),
.os = .wasi,
.abi = .none,
},
@ -673,9 +675,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
, &[_][]const u8{
"tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs",
});
tc.target = tests.Target{
.Cross = tests.CrossTarget{
tc.target = Target{
.Cross = .{
.arch = .x86_64,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
.os = .linux,
.abi = .gnu,
},

View File

@ -529,6 +529,10 @@ test "comptime_int xor" {
}
test "f128" {
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
test_f128();
comptime test_f128();
}
@ -627,6 +631,10 @@ test "NaN comparison" {
// TODO: https://github.com/ziglang/zig/issues/3338
return error.SkipZigTest;
}
if (std.Target.current.isWindows()) {
// TODO https://github.com/ziglang/zig/issues/508
return error.SkipZigTest;
}
testNanEqNan(f16);
testNanEqNan(f32);
testNanEqNan(f64);

View File

@ -38,236 +38,260 @@ const TestTarget = struct {
disable_native: bool = false,
};
const test_targets = [_]TestTarget{
TestTarget{},
TestTarget{
.link_libc = true,
},
TestTarget{
.single_threaded = true,
},
const test_targets = blk: {
// getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm
// (where N is roughly 160, which technically makes it O(1), but it adds up to a
// lot of branches)
@setEvalBranchQuota(50000);
break :blk [_]TestTarget{
TestTarget{},
TestTarget{
.link_libc = true,
},
TestTarget{
.single_threaded = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .none,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .none,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
},
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .gnu,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .gnu,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
},
},
.link_libc = true,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .musl,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
.abi = .musl,
},
},
.link_libc = true,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .i386,
.abi = .none,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .i386,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
.abi = .none,
},
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .i386,
.abi = .musl,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .i386,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
.abi = .musl,
},
},
.link_libc = true,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .none,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = Target.Arch{ .aarch64 = .v8a },
.cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
.abi = .none,
},
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .musl,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = Target.Arch{ .aarch64 = .v8a },
.cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
.abi = .musl,
},
},
.link_libc = true,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .gnu,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = Target.Arch{ .aarch64 = .v8a },
.cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
.abi = .gnu,
},
},
.link_libc = true,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
.abi = .none,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = Target.Arch{ .arm = .v8a },
.cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
.abi = .none,
},
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
.abi = .musleabihf,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = Target.Arch{ .arm = .v8a },
.cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
.abi = .musleabihf,
},
},
.link_libc = true,
},
// TODO https://github.com/ziglang/zig/issues/3287
//TestTarget{
// .target = Target{
// .Cross = CrossTarget{
// .os = .linux,
// .arch = Target.Arch{ .arm = .v8a },
// .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
// .abi = .gnueabihf,
// },
// },
// .link_libc = true,
//},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .mipsel,
.cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
.abi = .none,
},
},
},
.link_libc = true,
},
// TODO https://github.com/ziglang/zig/issues/3287
//TestTarget{
// .target = Target{
// .Cross = CrossTarget{
// .os = .linux,
// .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
// .abi = .gnueabihf,
// },
// },
// .link_libc = true,
//},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .mipsel,
.cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
.abi = .musl,
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .mipsel,
.abi = .none,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .macosx,
.arch = .x86_64,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
.abi = .gnu,
},
},
// TODO https://github.com/ziglang/zig/issues/3295
.disable_native = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .i386,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
.abi = .msvc,
},
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .mipsel,
.abi = .musl,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
.abi = .msvc,
},
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .macosx,
.arch = .x86_64,
.abi = .gnu,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .i386,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
.abi = .gnu,
},
},
.link_libc = true,
},
// TODO https://github.com/ziglang/zig/issues/3295
.disable_native = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .i386,
.abi = .msvc,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
.abi = .gnu,
},
},
.link_libc = true,
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.abi = .msvc,
},
// Do the release tests last because they take a long time
TestTarget{
.mode = .ReleaseFast,
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .i386,
.abi = .gnu,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseFast,
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.abi = .gnu,
},
TestTarget{
.mode = .ReleaseFast,
.single_threaded = true,
},
.link_libc = true,
},
// Do the release tests last because they take a long time
TestTarget{
.mode = .ReleaseFast,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseFast,
},
TestTarget{
.mode = .ReleaseFast,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSafe,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSafe,
},
TestTarget{
.mode = .ReleaseSafe,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSafe,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSafe,
},
TestTarget{
.mode = .ReleaseSafe,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSmall,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSmall,
},
TestTarget{
.mode = .ReleaseSmall,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSmall,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSmall,
},
TestTarget{
.mode = .ReleaseSmall,
.single_threaded = true,
},
};
};
const max_stdout_size = 1 * 1024 * 1024; // 1 MB

View File

@ -1,5 +1,6 @@
const tests = @import("tests.zig");
const builtin = @import("builtin");
const Target = @import("std").Target;
pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("array initializer w/ typedef",
@ -1030,7 +1031,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
});
cases.addWithTarget("Calling convention", tests.Target{
.Cross = .{ .os = .linux, .arch = .i386, .abi = .none },
.Cross = .{
.os = .linux,
.arch = .i386,
.abi = .none,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
},
},
\\void __attribute__((fastcall)) foo1(float *a);
\\void __attribute__((stdcall)) foo2(float *a);
@ -1046,7 +1052,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
});
cases.addWithTarget("Calling convention", tests.Target{
.Cross = .{ .os = .linux, .arch = .{ .arm = .v8_5a }, .abi = .none },
.Cross = .{
.os = .linux,
.arch = .{ .arm = .v8_5a },
.abi = .none,
.cpu_features = (Target.Arch{ .arm = .v8_5a }).getBaselineCpuFeatures(),
},
},
\\void __attribute__((pcs("aapcs"))) foo1(float *a);
\\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a);
@ -1056,7 +1067,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
});
cases.addWithTarget("Calling convention", tests.Target{
.Cross = .{ .os = .linux, .arch = .{ .aarch64 = .v8_5a }, .abi = .none },
.Cross = .{
.os = .linux,
.arch = .{ .aarch64 = .v8_5a },
.abi = .none,
.cpu_features = (Target.Arch{ .aarch64 = .v8_5a }).getBaselineCpuFeatures(),
},
},
\\void __attribute__((aarch64_vector_pcs)) foo1(float *a);
, &[_][]const u8{