Merge remote-tracking branch 'origin/master' into llvm10
This commit is contained in:
commit
a95dce15ae
@ -10113,7 +10113,7 @@ Available libcs:
|
||||
The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system
|
||||
abstractions, and thus takes additional work to support more platforms.
|
||||
Not all standard library code requires operating system abstractions, however,
|
||||
so things such as generic data structures work an all above platforms.
|
||||
so things such as generic data structures work on all above platforms.
|
||||
</p>
|
||||
<p>The current list of targets supported by the Zig Standard Library is:</p>
|
||||
<ul>
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
@ -1148,6 +1149,7 @@ pub const LibExeObjStep = struct {
|
||||
name_prefix: []const u8,
|
||||
filter: ?[]const u8,
|
||||
single_threaded: bool,
|
||||
code_model: builtin.CodeModel = .default,
|
||||
|
||||
root_src: ?FileSource,
|
||||
out_h_filename: []const u8,
|
||||
@ -1375,6 +1377,7 @@ pub const LibExeObjStep = struct {
|
||||
.arch = target_arch,
|
||||
.os = target_os,
|
||||
.abi = target_abi,
|
||||
.cpu_features = target_arch.getBaselineCpuFeatures(),
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -1968,11 +1971,56 @@ pub const LibExeObjStep = struct {
|
||||
try zig_args.append("-fno-sanitize-c");
|
||||
}
|
||||
|
||||
if (self.code_model != .default) {
|
||||
try zig_args.append("-code-model");
|
||||
try zig_args.append(@tagName(self.code_model));
|
||||
}
|
||||
|
||||
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;
|
||||
if (self.target.getArch().subArchFeature()) |sub_arch_index| {
|
||||
populated_cpu_features.addFeature(sub_arch_index);
|
||||
}
|
||||
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());
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
pub usingnamespace @import("builtin");
|
||||
|
||||
/// Deprecated: use `std.Target`.
|
||||
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`.
|
||||
@ -82,6 +91,21 @@ pub const AtomicRmwOp = enum {
|
||||
Min,
|
||||
};
|
||||
|
||||
/// The code model puts constraints on the location of symbols and the size of code and data.
|
||||
/// The selection of a code model is a trade off on speed and restrictions that needs to be selected on a per application basis to meet its requirements.
|
||||
/// A slightly more detailed explanation can be found in (for example) the [System V Application Binary Interface (x86_64)](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf) 3.5.1.
|
||||
///
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const CodeModel = enum {
|
||||
default,
|
||||
tiny,
|
||||
small,
|
||||
kernel,
|
||||
medium,
|
||||
large,
|
||||
};
|
||||
|
||||
/// This data structure is used by the Zig language code generation and
|
||||
/// therefore must be kept in sync with the compiler implementation.
|
||||
pub const Mode = enum {
|
||||
|
@ -2,6 +2,12 @@ const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const page_size = std.mem.page_size;
|
||||
|
||||
pub const tokenizer = @import("c/tokenizer.zig");
|
||||
pub const Token = tokenizer.Token;
|
||||
pub const Tokenizer = tokenizer.Tokenizer;
|
||||
pub const parse = @import("c/parse.zig").parse;
|
||||
pub const ast = @import("c/ast.zig");
|
||||
|
||||
pub usingnamespace @import("os/bits.zig");
|
||||
|
||||
pub usingnamespace switch (builtin.os) {
|
||||
|
681
lib/std/c/ast.zig
Normal file
681
lib/std/c/ast.zig
Normal file
@ -0,0 +1,681 @@
|
||||
const std = @import("std");
|
||||
const SegmentedList = std.SegmentedList;
|
||||
const Token = std.c.Token;
|
||||
const Source = std.c.tokenizer.Source;
|
||||
|
||||
pub const TokenIndex = usize;
|
||||
|
||||
pub const Tree = struct {
|
||||
tokens: TokenList,
|
||||
sources: SourceList,
|
||||
root_node: *Node.Root,
|
||||
arena_allocator: std.heap.ArenaAllocator,
|
||||
msgs: MsgList,
|
||||
|
||||
pub const SourceList = SegmentedList(Source, 4);
|
||||
pub const TokenList = Source.TokenList;
|
||||
pub const MsgList = SegmentedList(Msg, 0);
|
||||
|
||||
pub fn deinit(self: *Tree) void {
|
||||
// Here we copy the arena allocator into stack memory, because
|
||||
// otherwise it would destroy itself while it was still working.
|
||||
var arena_allocator = self.arena_allocator;
|
||||
arena_allocator.deinit();
|
||||
// self is destroyed
|
||||
}
|
||||
|
||||
pub fn tokenSlice(tree: *Tree, token: TokenIndex) []const u8 {
|
||||
return tree.tokens.at(token).slice();
|
||||
}
|
||||
|
||||
pub fn tokenEql(tree: *Tree, a: TokenIndex, b: TokenIndex) bool {
|
||||
const atok = tree.tokens.at(a);
|
||||
const btok = tree.tokens.at(b);
|
||||
return atok.eql(btok.*);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Msg = struct {
|
||||
kind: enum {
|
||||
Error,
|
||||
Warning,
|
||||
Note,
|
||||
},
|
||||
inner: Error,
|
||||
};
|
||||
|
||||
pub const Error = union(enum) {
|
||||
InvalidToken: SingleTokenError("invalid token '{}'"),
|
||||
ExpectedToken: ExpectedToken,
|
||||
ExpectedExpr: SingleTokenError("expected expression, found '{}'"),
|
||||
ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
|
||||
ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
|
||||
ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
|
||||
ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),
|
||||
ExpectedEnumField: SingleTokenError("expected enum field, found '{}'"),
|
||||
ExpectedType: SingleTokenError("expected enum field, found '{}'"),
|
||||
InvalidTypeSpecifier: InvalidTypeSpecifier,
|
||||
InvalidStorageClass: SingleTokenError("invalid storage class, found '{}'"),
|
||||
InvalidDeclarator: SimpleError("invalid declarator"),
|
||||
DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
|
||||
DuplicateSpecifier: SingleTokenError("duplicate declaration specifier '{}'"),
|
||||
MustUseKwToRefer: MustUseKwToRefer,
|
||||
FnSpecOnNonFn: SingleTokenError("function specifier '{}' on non function"),
|
||||
NothingDeclared: SimpleError("declaration doesn't declare anything"),
|
||||
QualifierIgnored: SingleTokenError("qualifier '{}' ignored"),
|
||||
|
||||
pub fn render(self: *const Error, tree: *Tree, stream: var) !void {
|
||||
switch (self.*) {
|
||||
.InvalidToken => |*x| return x.render(tree, stream),
|
||||
.ExpectedToken => |*x| return x.render(tree, stream),
|
||||
.ExpectedExpr => |*x| return x.render(tree, stream),
|
||||
.ExpectedTypeName => |*x| return x.render(tree, stream),
|
||||
.ExpectedDeclarator => |*x| return x.render(tree, stream),
|
||||
.ExpectedFnBody => |*x| return x.render(tree, stream),
|
||||
.ExpectedInitializer => |*x| return x.render(tree, stream),
|
||||
.ExpectedEnumField => |*x| return x.render(tree, stream),
|
||||
.ExpectedType => |*x| return x.render(tree, stream),
|
||||
.InvalidTypeSpecifier => |*x| return x.render(tree, stream),
|
||||
.InvalidStorageClass => |*x| return x.render(tree, stream),
|
||||
.InvalidDeclarator => |*x| return x.render(tree, stream),
|
||||
.DuplicateQualifier => |*x| return x.render(tree, stream),
|
||||
.DuplicateSpecifier => |*x| return x.render(tree, stream),
|
||||
.MustUseKwToRefer => |*x| return x.render(tree, stream),
|
||||
.FnSpecOnNonFn => |*x| return x.render(tree, stream),
|
||||
.NothingDeclared => |*x| return x.render(tree, stream),
|
||||
.QualifierIgnored => |*x| return x.render(tree, stream),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn loc(self: *const Error) TokenIndex {
|
||||
switch (self.*) {
|
||||
.InvalidToken => |x| return x.token,
|
||||
.ExpectedToken => |x| return x.token,
|
||||
.ExpectedExpr => |x| return x.token,
|
||||
.ExpectedTypeName => |x| return x.token,
|
||||
.ExpectedDeclarator => |x| return x.token,
|
||||
.ExpectedFnBody => |x| return x.token,
|
||||
.ExpectedInitializer => |x| return x.token,
|
||||
.ExpectedEnumField => |x| return x.token,
|
||||
.ExpectedType => |*x| return x.token,
|
||||
.InvalidTypeSpecifier => |x| return x.token,
|
||||
.InvalidStorageClass => |x| return x.token,
|
||||
.InvalidDeclarator => |x| return x.token,
|
||||
.DuplicateQualifier => |x| return x.token,
|
||||
.DuplicateSpecifier => |x| return x.token,
|
||||
.MustUseKwToRefer => |*x| return x.name,
|
||||
.FnSpecOnNonFn => |*x| return x.name,
|
||||
.NothingDeclared => |*x| return x.name,
|
||||
.QualifierIgnored => |*x| return x.name,
|
||||
}
|
||||
}
|
||||
|
||||
pub const ExpectedToken = struct {
|
||||
token: TokenIndex,
|
||||
expected_id: @TagType(Token.Id),
|
||||
|
||||
pub fn render(self: *const ExpectedToken, tree: *Tree, stream: var) !void {
|
||||
const found_token = tree.tokens.at(self.token);
|
||||
if (found_token.id == .Invalid) {
|
||||
return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
|
||||
} else {
|
||||
const token_name = found_token.id.symbol();
|
||||
return stream.print("expected '{}', found '{}'", .{ self.expected_id.symbol(), token_name });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const InvalidTypeSpecifier = struct {
|
||||
token: TokenIndex,
|
||||
type_spec: *Node.TypeSpec,
|
||||
|
||||
pub fn render(self: *const ExpectedToken, tree: *Tree, stream: var) !void {
|
||||
try stream.write("invalid type specifier '");
|
||||
try type_spec.spec.print(tree, stream);
|
||||
const token_name = tree.tokens.at(self.token).id.symbol();
|
||||
return stream.print("{}'", .{token_name});
|
||||
}
|
||||
};
|
||||
|
||||
pub const MustUseKwToRefer = struct {
|
||||
kw: TokenIndex,
|
||||
name: TokenIndex,
|
||||
|
||||
pub fn render(self: *const ExpectedToken, tree: *Tree, stream: var) !void {
|
||||
return stream.print("must use '{}' tag to refer to type '{}'", .{ tree.slice(kw), tree.slice(name) });
|
||||
}
|
||||
};
|
||||
|
||||
fn SingleTokenError(comptime msg: []const u8) type {
|
||||
return struct {
|
||||
token: TokenIndex,
|
||||
|
||||
pub fn render(self: *const @This(), tree: *Tree, stream: var) !void {
|
||||
const actual_token = tree.tokens.at(self.token);
|
||||
return stream.print(msg, .{actual_token.id.symbol()});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn SimpleError(comptime msg: []const u8) type {
|
||||
return struct {
|
||||
const ThisError = @This();
|
||||
|
||||
token: TokenIndex,
|
||||
|
||||
pub fn render(self: *const ThisError, tokens: *Tree.TokenList, stream: var) !void {
|
||||
return stream.write(msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Type = struct {
|
||||
pub const TypeList = std.SegmentedList(*Type, 4);
|
||||
@"const": bool = false,
|
||||
atomic: bool = false,
|
||||
@"volatile": bool = false,
|
||||
restrict: bool = false,
|
||||
|
||||
id: union(enum) {
|
||||
Int: struct {
|
||||
id: Id,
|
||||
is_signed: bool,
|
||||
|
||||
pub const Id = enum {
|
||||
Char,
|
||||
Short,
|
||||
Int,
|
||||
Long,
|
||||
LongLong,
|
||||
};
|
||||
},
|
||||
Float: struct {
|
||||
id: Id,
|
||||
|
||||
pub const Id = enum {
|
||||
Float,
|
||||
Double,
|
||||
LongDouble,
|
||||
};
|
||||
},
|
||||
Pointer: *Type,
|
||||
Function: struct {
|
||||
return_type: *Type,
|
||||
param_types: TypeList,
|
||||
},
|
||||
Typedef: *Type,
|
||||
Record: *Node.RecordType,
|
||||
Enum: *Node.EnumType,
|
||||
|
||||
/// Special case for macro parameters that can be any type.
|
||||
/// Only present if `retain_macros == true`.
|
||||
Macro,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Node = struct {
|
||||
id: Id,
|
||||
|
||||
pub const Id = enum {
|
||||
Root,
|
||||
EnumField,
|
||||
RecordField,
|
||||
RecordDeclarator,
|
||||
JumpStmt,
|
||||
ExprStmt,
|
||||
LabeledStmt,
|
||||
CompoundStmt,
|
||||
IfStmt,
|
||||
SwitchStmt,
|
||||
WhileStmt,
|
||||
DoStmt,
|
||||
ForStmt,
|
||||
StaticAssert,
|
||||
Declarator,
|
||||
Pointer,
|
||||
FnDecl,
|
||||
Typedef,
|
||||
VarDecl,
|
||||
};
|
||||
|
||||
pub const Root = struct {
|
||||
base: Node = Node{ .id = .Root },
|
||||
decls: DeclList,
|
||||
eof: TokenIndex,
|
||||
|
||||
pub const DeclList = SegmentedList(*Node, 4);
|
||||
};
|
||||
|
||||
pub const DeclSpec = struct {
|
||||
storage_class: union(enum) {
|
||||
Auto: TokenIndex,
|
||||
Extern: TokenIndex,
|
||||
Register: TokenIndex,
|
||||
Static: TokenIndex,
|
||||
Typedef: TokenIndex,
|
||||
None,
|
||||
} = .None,
|
||||
thread_local: ?TokenIndex = null,
|
||||
type_spec: TypeSpec = TypeSpec{},
|
||||
fn_spec: union(enum) {
|
||||
Inline: TokenIndex,
|
||||
Noreturn: TokenIndex,
|
||||
None,
|
||||
} = .None,
|
||||
align_spec: ?struct {
|
||||
alignas: TokenIndex,
|
||||
expr: *Node,
|
||||
rparen: TokenIndex,
|
||||
} = null,
|
||||
};
|
||||
|
||||
pub const TypeSpec = struct {
|
||||
qual: TypeQual = TypeQual{},
|
||||
spec: union(enum) {
|
||||
/// error or default to int
|
||||
None,
|
||||
Void: TokenIndex,
|
||||
Char: struct {
|
||||
sign: ?TokenIndex = null,
|
||||
char: TokenIndex,
|
||||
},
|
||||
Short: struct {
|
||||
sign: ?TokenIndex = null,
|
||||
short: TokenIndex = null,
|
||||
int: ?TokenIndex = null,
|
||||
},
|
||||
Int: struct {
|
||||
sign: ?TokenIndex = null,
|
||||
int: ?TokenIndex = null,
|
||||
},
|
||||
Long: struct {
|
||||
sign: ?TokenIndex = null,
|
||||
long: TokenIndex,
|
||||
longlong: ?TokenIndex = null,
|
||||
int: ?TokenIndex = null,
|
||||
},
|
||||
Float: struct {
|
||||
float: TokenIndex,
|
||||
complex: ?TokenIndex = null,
|
||||
},
|
||||
Double: struct {
|
||||
long: ?TokenIndex = null,
|
||||
double: ?TokenIndex,
|
||||
complex: ?TokenIndex = null,
|
||||
},
|
||||
Bool: TokenIndex,
|
||||
Atomic: struct {
|
||||
atomic: TokenIndex,
|
||||
typename: *Node,
|
||||
rparen: TokenIndex,
|
||||
},
|
||||
Enum: *EnumType,
|
||||
Record: *RecordType,
|
||||
Typedef: struct {
|
||||
sym: TokenIndex,
|
||||
sym_type: *Type,
|
||||
},
|
||||
|
||||
pub fn print(self: *@This(), self: *const @This(), tree: *Tree, stream: var) !void {
|
||||
switch (self.spec) {
|
||||
.None => unreachable,
|
||||
.Void => |index| try stream.write(tree.slice(index)),
|
||||
.Char => |char| {
|
||||
if (char.sign) |s| {
|
||||
try stream.write(tree.slice(s));
|
||||
try stream.writeByte(' ');
|
||||
}
|
||||
try stream.write(tree.slice(char.char));
|
||||
},
|
||||
.Short => |short| {
|
||||
if (short.sign) |s| {
|
||||
try stream.write(tree.slice(s));
|
||||
try stream.writeByte(' ');
|
||||
}
|
||||
try stream.write(tree.slice(short.short));
|
||||
if (short.int) |i| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(i));
|
||||
}
|
||||
},
|
||||
.Int => |int| {
|
||||
if (int.sign) |s| {
|
||||
try stream.write(tree.slice(s));
|
||||
try stream.writeByte(' ');
|
||||
}
|
||||
if (int.int) |i| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(i));
|
||||
}
|
||||
},
|
||||
.Long => |long| {
|
||||
if (long.sign) |s| {
|
||||
try stream.write(tree.slice(s));
|
||||
try stream.writeByte(' ');
|
||||
}
|
||||
try stream.write(tree.slice(long.long));
|
||||
if (long.longlong) |l| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(l));
|
||||
}
|
||||
if (long.int) |i| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(i));
|
||||
}
|
||||
},
|
||||
.Float => |float| {
|
||||
try stream.write(tree.slice(float.float));
|
||||
if (float.complex) |c| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(c));
|
||||
}
|
||||
},
|
||||
.Double => |double| {
|
||||
if (double.long) |l| {
|
||||
try stream.write(tree.slice(l));
|
||||
try stream.writeByte(' ');
|
||||
}
|
||||
try stream.write(tree.slice(double.double));
|
||||
if (double.complex) |c| {
|
||||
try stream.writeByte(' ');
|
||||
try stream.write(tree.slice(c));
|
||||
}
|
||||
},
|
||||
.Bool => |index| try stream.write(tree.slice(index)),
|
||||
.Typedef => |typedef| try stream.write(tree.slice(typedef.sym)),
|
||||
else => try stream.print("TODO print {}", self.spec),
|
||||
}
|
||||
}
|
||||
} = .None,
|
||||
};
|
||||
|
||||
pub const EnumType = struct {
|
||||
tok: TokenIndex,
|
||||
name: ?TokenIndex,
|
||||
body: ?struct {
|
||||
lbrace: TokenIndex,
|
||||
|
||||
/// always EnumField
|
||||
fields: FieldList,
|
||||
rbrace: TokenIndex,
|
||||
},
|
||||
|
||||
pub const FieldList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const EnumField = struct {
|
||||
base: Node = Node{ .id = .EnumField },
|
||||
name: TokenIndex,
|
||||
value: ?*Node,
|
||||
};
|
||||
|
||||
pub const RecordType = struct {
|
||||
tok: TokenIndex,
|
||||
kind: enum {
|
||||
Struct,
|
||||
Union,
|
||||
},
|
||||
name: ?TokenIndex,
|
||||
body: ?struct {
|
||||
lbrace: TokenIndex,
|
||||
|
||||
/// RecordField or StaticAssert
|
||||
fields: FieldList,
|
||||
rbrace: TokenIndex,
|
||||
},
|
||||
|
||||
pub const FieldList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const RecordField = struct {
|
||||
base: Node = Node{ .id = .RecordField },
|
||||
type_spec: TypeSpec,
|
||||
declarators: DeclaratorList,
|
||||
semicolon: TokenIndex,
|
||||
|
||||
pub const DeclaratorList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const RecordDeclarator = struct {
|
||||
base: Node = Node{ .id = .RecordDeclarator },
|
||||
declarator: ?*Declarator,
|
||||
bit_field_expr: ?*Expr,
|
||||
};
|
||||
|
||||
pub const TypeQual = struct {
|
||||
@"const": ?TokenIndex = null,
|
||||
atomic: ?TokenIndex = null,
|
||||
@"volatile": ?TokenIndex = null,
|
||||
restrict: ?TokenIndex = null,
|
||||
};
|
||||
|
||||
pub const JumpStmt = struct {
|
||||
base: Node = Node{ .id = .JumpStmt },
|
||||
ltoken: TokenIndex,
|
||||
kind: union(enum) {
|
||||
Break,
|
||||
Continue,
|
||||
Return: ?*Node,
|
||||
Goto: TokenIndex,
|
||||
},
|
||||
semicolon: TokenIndex,
|
||||
};
|
||||
|
||||
pub const ExprStmt = struct {
|
||||
base: Node = Node{ .id = .ExprStmt },
|
||||
expr: ?*Expr,
|
||||
semicolon: TokenIndex,
|
||||
};
|
||||
|
||||
pub const LabeledStmt = struct {
|
||||
base: Node = Node{ .id = .LabeledStmt },
|
||||
kind: union(enum) {
|
||||
Label: TokenIndex,
|
||||
Case: TokenIndex,
|
||||
Default: TokenIndex,
|
||||
},
|
||||
stmt: *Node,
|
||||
};
|
||||
|
||||
pub const CompoundStmt = struct {
|
||||
base: Node = Node{ .id = .CompoundStmt },
|
||||
lbrace: TokenIndex,
|
||||
statements: StmtList,
|
||||
rbrace: TokenIndex,
|
||||
|
||||
pub const StmtList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const IfStmt = struct {
|
||||
base: Node = Node{ .id = .IfStmt },
|
||||
@"if": TokenIndex,
|
||||
cond: *Node,
|
||||
body: *Node,
|
||||
@"else": ?struct {
|
||||
tok: TokenIndex,
|
||||
body: *Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const SwitchStmt = struct {
|
||||
base: Node = Node{ .id = .SwitchStmt },
|
||||
@"switch": TokenIndex,
|
||||
expr: *Expr,
|
||||
rparen: TokenIndex,
|
||||
stmt: *Node,
|
||||
};
|
||||
|
||||
pub const WhileStmt = struct {
|
||||
base: Node = Node{ .id = .WhileStmt },
|
||||
@"while": TokenIndex,
|
||||
cond: *Expr,
|
||||
rparen: TokenIndex,
|
||||
body: *Node,
|
||||
};
|
||||
|
||||
pub const DoStmt = struct {
|
||||
base: Node = Node{ .id = .DoStmt },
|
||||
do: TokenIndex,
|
||||
body: *Node,
|
||||
@"while": TokenIndex,
|
||||
cond: *Expr,
|
||||
semicolon: TokenIndex,
|
||||
};
|
||||
|
||||
pub const ForStmt = struct {
|
||||
base: Node = Node{ .id = .ForStmt },
|
||||
@"for": TokenIndex,
|
||||
init: ?*Node,
|
||||
cond: ?*Expr,
|
||||
semicolon: TokenIndex,
|
||||
incr: ?*Expr,
|
||||
rparen: TokenIndex,
|
||||
body: *Node,
|
||||
};
|
||||
|
||||
pub const StaticAssert = struct {
|
||||
base: Node = Node{ .id = .StaticAssert },
|
||||
assert: TokenIndex,
|
||||
expr: *Node,
|
||||
semicolon: TokenIndex,
|
||||
};
|
||||
|
||||
pub const Declarator = struct {
|
||||
base: Node = Node{ .id = .Declarator },
|
||||
pointer: ?*Pointer,
|
||||
prefix: union(enum) {
|
||||
None,
|
||||
Identifer: TokenIndex,
|
||||
Complex: struct {
|
||||
lparen: TokenIndex,
|
||||
inner: *Node,
|
||||
rparen: TokenIndex,
|
||||
},
|
||||
},
|
||||
suffix: union(enum) {
|
||||
None,
|
||||
Fn: struct {
|
||||
lparen: TokenIndex,
|
||||
params: Params,
|
||||
rparen: TokenIndex,
|
||||
},
|
||||
Array: Arrays,
|
||||
},
|
||||
|
||||
pub const Arrays = std.SegmentedList(*Array, 2);
|
||||
pub const Params = std.SegmentedList(*Param, 4);
|
||||
};
|
||||
|
||||
pub const Array = struct {
|
||||
lbracket: TokenIndex,
|
||||
inner: union(enum) {
|
||||
Inferred,
|
||||
Unspecified: TokenIndex,
|
||||
Variable: struct {
|
||||
asterisk: ?TokenIndex,
|
||||
static: ?TokenIndex,
|
||||
qual: TypeQual,
|
||||
expr: *Expr,
|
||||
},
|
||||
},
|
||||
rbracket: TokenIndex,
|
||||
};
|
||||
|
||||
pub const Pointer = struct {
|
||||
base: Node = Node{ .id = .Pointer },
|
||||
asterisk: TokenIndex,
|
||||
qual: TypeQual,
|
||||
pointer: ?*Pointer,
|
||||
};
|
||||
|
||||
pub const Param = struct {
|
||||
kind: union(enum) {
|
||||
Variable,
|
||||
Old: TokenIndex,
|
||||
Normal: struct {
|
||||
decl_spec: *DeclSpec,
|
||||
declarator: *Node,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
pub const FnDecl = struct {
|
||||
base: Node = Node{ .id = .FnDecl },
|
||||
decl_spec: DeclSpec,
|
||||
declarator: *Declarator,
|
||||
old_decls: OldDeclList,
|
||||
body: ?*CompoundStmt,
|
||||
|
||||
pub const OldDeclList = SegmentedList(*Node, 0);
|
||||
};
|
||||
|
||||
pub const Typedef = struct {
|
||||
base: Node = Node{ .id = .Typedef },
|
||||
decl_spec: DeclSpec,
|
||||
declarators: DeclaratorList,
|
||||
semicolon: TokenIndex,
|
||||
|
||||
pub const DeclaratorList = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const VarDecl = struct {
|
||||
base: Node = Node{ .id = .VarDecl },
|
||||
decl_spec: DeclSpec,
|
||||
initializers: Initializers,
|
||||
semicolon: TokenIndex,
|
||||
|
||||
pub const Initializers = Root.DeclList;
|
||||
};
|
||||
|
||||
pub const Initialized = struct {
|
||||
base: Node = Node{ .id = Initialized },
|
||||
declarator: *Declarator,
|
||||
eq: TokenIndex,
|
||||
init: Initializer,
|
||||
};
|
||||
|
||||
pub const Initializer = union(enum) {
|
||||
list: struct {
|
||||
initializers: InitializerList,
|
||||
rbrace: TokenIndex,
|
||||
},
|
||||
expr: *Expr,
|
||||
pub const InitializerList = std.SegmentedList(*Initializer, 4);
|
||||
};
|
||||
|
||||
pub const Macro = struct {
|
||||
base: Node = Node{ .id = Macro },
|
||||
kind: union(enum) {
|
||||
Undef: []const u8,
|
||||
Fn: struct {
|
||||
params: []const []const u8,
|
||||
expr: *Expr,
|
||||
},
|
||||
Expr: *Expr,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
pub const Expr = struct {
|
||||
id: Id,
|
||||
ty: *Type,
|
||||
value: union(enum) {
|
||||
None,
|
||||
},
|
||||
|
||||
pub const Id = enum {
|
||||
Infix,
|
||||
Literal,
|
||||
};
|
||||
|
||||
pub const Infix = struct {
|
||||
base: Expr = Expr{ .id = .Infix },
|
||||
lhs: *Expr,
|
||||
op_token: TokenIndex,
|
||||
op: Op,
|
||||
rhs: *Expr,
|
||||
|
||||
pub const Op = enum {};
|
||||
};
|
||||
};
|
@ -7,7 +7,10 @@ usingnamespace @import("../os/bits.zig");
|
||||
|
||||
extern "c" fn __error() *c_int;
|
||||
pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
|
||||
pub extern "c" fn _dyld_image_count() u32;
|
||||
pub extern "c" fn _dyld_get_image_header(image_index: u32) ?*mach_header;
|
||||
pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize;
|
||||
pub extern "c" fn _dyld_get_image_name(image_index: u32) [*:0]const u8;
|
||||
|
||||
pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;
|
||||
|
||||
|
1431
lib/std/c/parse.zig
Normal file
1431
lib/std/c/parse.zig
Normal file
File diff suppressed because it is too large
Load Diff
1583
lib/std/c/tokenizer.zig
Normal file
1583
lib/std/c/tokenizer.zig
Normal file
File diff suppressed because it is too large
Load Diff
1071
lib/std/debug.zig
1071
lib/std/debug.zig
File diff suppressed because it is too large
Load Diff
@ -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..];
|
||||
|
@ -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;
|
||||
|
@ -15,7 +15,7 @@ pub const Murmur2_32 = struct {
|
||||
const m: u32 = 0x5bd1e995;
|
||||
const len = @truncate(u32, str.len);
|
||||
var h1: u32 = seed ^ len;
|
||||
for (@ptrCast([*]allowzero align(1) const u32, str.ptr)[0..(len >> 2)]) |v| {
|
||||
for (@ptrCast([*]align(1) const u32, str.ptr)[0..(len >> 2)]) |v| {
|
||||
var k1: u32 = v;
|
||||
if (builtin.endian == builtin.Endian.Big)
|
||||
k1 = @byteSwap(u32, k1);
|
||||
@ -100,7 +100,7 @@ pub const Murmur2_64 = struct {
|
||||
const m: u64 = 0xc6a4a7935bd1e995;
|
||||
const len = @as(u64, str.len);
|
||||
var h1: u64 = seed ^ (len *% m);
|
||||
for (@ptrCast([*]allowzero align(1) const u64, str.ptr)[0..@intCast(usize, len >> 3)]) |v| {
|
||||
for (@ptrCast([*]align(1) const u64, str.ptr)[0..@intCast(usize, len >> 3)]) |v| {
|
||||
var k1: u64 = v;
|
||||
if (builtin.endian == builtin.Endian.Big)
|
||||
k1 = @byteSwap(u64, k1);
|
||||
@ -180,7 +180,7 @@ pub const Murmur3_32 = struct {
|
||||
const c2: u32 = 0x1b873593;
|
||||
const len = @truncate(u32, str.len);
|
||||
var h1: u32 = seed;
|
||||
for (@ptrCast([*]allowzero align(1) const u32, str.ptr)[0..(len >> 2)]) |v| {
|
||||
for (@ptrCast([*]align(1) const u32, str.ptr)[0..(len >> 2)]) |v| {
|
||||
var k1: u32 = v;
|
||||
if (builtin.endian == builtin.Endian.Big)
|
||||
k1 = @byteSwap(u32, k1);
|
||||
|
@ -172,7 +172,7 @@ pub const Headers = struct {
|
||||
var dex = HeaderIndexList.init(self.allocator);
|
||||
try dex.append(n - 1);
|
||||
errdefer dex.deinit();
|
||||
_ = try self.index.put(name, dex);
|
||||
_ = try self.index.put(name_dup, dex);
|
||||
}
|
||||
self.data.appendAssumeCapacity(entry);
|
||||
}
|
||||
|
@ -45,10 +45,14 @@ pub fn OutStream(comptime WriteError: type) type {
|
||||
}
|
||||
|
||||
pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void {
|
||||
const slice = @as(*const [1]u8, &byte)[0..];
|
||||
var i: usize = 0;
|
||||
while (i < n) : (i += 1) {
|
||||
try self.writeFn(self, slice);
|
||||
var bytes: [256]u8 = undefined;
|
||||
mem.set(u8, bytes[0..], byte);
|
||||
|
||||
var remaining: usize = n;
|
||||
while (remaining > 0) {
|
||||
const to_write = std.math.min(remaining, bytes.len);
|
||||
try self.writeFn(self, bytes[0..to_write]);
|
||||
remaining -= to_write;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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))));
|
||||
|
@ -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)));
|
||||
|
@ -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)));
|
||||
|
@ -175,6 +175,7 @@ pub const Allocator = struct {
|
||||
|
||||
const old_byte_slice = @sliceToBytes(old_mem);
|
||||
const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
|
||||
// Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
|
||||
const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
|
||||
assert(byte_slice.len == byte_count);
|
||||
if (new_n > old_mem.len) {
|
||||
@ -221,6 +222,7 @@ pub const Allocator = struct {
|
||||
const byte_count = @sizeOf(T) * new_n;
|
||||
|
||||
const old_byte_slice = @sliceToBytes(old_mem);
|
||||
@memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);
|
||||
const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
|
||||
assert(byte_slice.len == byte_count);
|
||||
return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));
|
||||
@ -234,6 +236,7 @@ pub const Allocator = struct {
|
||||
const bytes_len = bytes.len + @boolToInt(Slice.sentinel != null);
|
||||
if (bytes_len == 0) return;
|
||||
const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
|
||||
@memset(non_const_ptr, undefined, bytes_len);
|
||||
const shrink_result = self.shrinkFn(self, non_const_ptr[0..bytes_len], Slice.alignment, 0, 1);
|
||||
assert(shrink_result.len == 0);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -2697,7 +2697,7 @@ pub fn dl_iterate_phdr(
|
||||
// the whole ELF image
|
||||
if (it.end()) {
|
||||
var info = dl_phdr_info{
|
||||
.dlpi_addr = elf_base,
|
||||
.dlpi_addr = 0,
|
||||
.dlpi_name = "/proc/self/exe",
|
||||
.dlpi_phdr = phdrs.ptr,
|
||||
.dlpi_phnum = ehdr.e_phnum,
|
||||
|
@ -1041,63 +1041,6 @@ pub fn uname(uts: *utsname) usize {
|
||||
return syscall1(SYS_uname, @ptrToInt(uts));
|
||||
}
|
||||
|
||||
// XXX: This should be weak
|
||||
extern const __ehdr_start: elf.Ehdr;
|
||||
|
||||
pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize {
|
||||
if (builtin.link_libc) {
|
||||
return std.c.dl_iterate_phdr(@ptrCast(std.c.dl_iterate_phdr_callback, callback), @ptrCast(?*c_void, data));
|
||||
}
|
||||
|
||||
const elf_base = @ptrToInt(&__ehdr_start);
|
||||
const n_phdr = __ehdr_start.e_phnum;
|
||||
const phdrs = (@intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff))[0..n_phdr];
|
||||
|
||||
var it = dl.linkmap_iterator(phdrs) catch return 0;
|
||||
|
||||
// The executable has no dynamic link segment, create a single entry for
|
||||
// the whole ELF image
|
||||
if (it.end()) {
|
||||
var info = dl_phdr_info{
|
||||
.dlpi_addr = elf_base,
|
||||
.dlpi_name = "/proc/self/exe",
|
||||
.dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff),
|
||||
.dlpi_phnum = __ehdr_start.e_phnum,
|
||||
};
|
||||
|
||||
return callback(&info, @sizeOf(dl_phdr_info), data);
|
||||
}
|
||||
|
||||
// Last return value from the callback function
|
||||
var last_r: isize = 0;
|
||||
while (it.next()) |entry| {
|
||||
var dlpi_phdr: usize = undefined;
|
||||
var dlpi_phnum: u16 = undefined;
|
||||
|
||||
if (entry.l_addr != 0) {
|
||||
const elf_header = @intToPtr(*elf.Ehdr, entry.l_addr);
|
||||
dlpi_phdr = entry.l_addr + elf_header.e_phoff;
|
||||
dlpi_phnum = elf_header.e_phnum;
|
||||
} else {
|
||||
// This is the running ELF image
|
||||
dlpi_phdr = elf_base + __ehdr_start.e_phoff;
|
||||
dlpi_phnum = __ehdr_start.e_phnum;
|
||||
}
|
||||
|
||||
var info = dl_phdr_info{
|
||||
.dlpi_addr = entry.l_addr,
|
||||
.dlpi_name = entry.l_name,
|
||||
.dlpi_phdr = @intToPtr([*]elf.Phdr, dlpi_phdr),
|
||||
.dlpi_phnum = dlpi_phnum,
|
||||
};
|
||||
|
||||
last_r = callback(&info, @sizeOf(dl_phdr_info), data);
|
||||
if (last_r != 0) break;
|
||||
}
|
||||
|
||||
return last_r;
|
||||
}
|
||||
|
||||
pub fn io_uring_setup(entries: u32, p: *io_uring_params) usize {
|
||||
return syscall2(SYS_io_uring_setup, entries, @ptrToInt(p));
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -186,8 +186,9 @@ fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {
|
||||
|
||||
if (phdr.p_type != elf.PT_LOAD) continue;
|
||||
|
||||
const reloc_addr = info.dlpi_addr + phdr.p_vaddr;
|
||||
// Find the ELF header
|
||||
const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset);
|
||||
const elf_header = @intToPtr(*elf.Ehdr, reloc_addr - phdr.p_offset);
|
||||
// Validate the magic
|
||||
if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return -1;
|
||||
// Consistency check
|
||||
|
@ -7,16 +7,14 @@ const builtin = @import("builtin");
|
||||
|
||||
/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
|
||||
pub fn insertionSort(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) void {
|
||||
{
|
||||
var i: usize = 1;
|
||||
while (i < items.len) : (i += 1) {
|
||||
const x = items[i];
|
||||
var j: usize = i;
|
||||
while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {
|
||||
items[j] = items[j - 1];
|
||||
}
|
||||
items[j] = x;
|
||||
var i: usize = 1;
|
||||
while (i < items.len) : (i += 1) {
|
||||
const x = items[i];
|
||||
var j: usize = i;
|
||||
while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {
|
||||
items[j] = items[j - 1];
|
||||
}
|
||||
items[j] = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,7 @@ comptime {
|
||||
@export(@import("compiler_rt/int.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
|
||||
@export(@import("compiler_rt/popcountdi2.zig").__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
|
||||
|
||||
@export(@import("compiler_rt/int.zig").__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
|
||||
@export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__muldi3", .linkage = linkage });
|
||||
@export(@import("compiler_rt/int.zig").__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
|
||||
@export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__divsi3", .linkage = linkage });
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Builtin functions that operate on integer types
|
||||
const builtin = @import("builtin");
|
||||
const testing = @import("std").testing;
|
||||
const maxInt = @import("std").math.maxInt;
|
||||
const minInt = @import("std").math.minInt;
|
||||
|
||||
const udivmod = @import("udivmod.zig").udivmod;
|
||||
|
||||
@ -578,3 +580,61 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
|
||||
const r: u32 = __umodsi3(a, b);
|
||||
testing.expect(r == expected_r);
|
||||
}
|
||||
|
||||
pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
|
||||
@setRuntimeSafety(builtin.is_test);
|
||||
|
||||
var ua = @bitCast(u32, a);
|
||||
var ub = @bitCast(u32, b);
|
||||
var r: u32 = 0;
|
||||
|
||||
while (ua > 0) {
|
||||
if ((ua & 1) != 0) r +%= ub;
|
||||
ua >>= 1;
|
||||
ub <<= 1;
|
||||
}
|
||||
|
||||
return @bitCast(i32, r);
|
||||
}
|
||||
|
||||
fn test_one_mulsi3(a: i32, b: i32, result: i32) void {
|
||||
testing.expectEqual(result, __mulsi3(a, b));
|
||||
}
|
||||
|
||||
test "mulsi3" {
|
||||
test_one_mulsi3(0, 0, 0);
|
||||
test_one_mulsi3(0, 1, 0);
|
||||
test_one_mulsi3(1, 0, 0);
|
||||
test_one_mulsi3(0, 10, 0);
|
||||
test_one_mulsi3(10, 0, 0);
|
||||
test_one_mulsi3(0, maxInt(i32), 0);
|
||||
test_one_mulsi3(maxInt(i32), 0, 0);
|
||||
test_one_mulsi3(0, -1, 0);
|
||||
test_one_mulsi3(-1, 0, 0);
|
||||
test_one_mulsi3(0, -10, 0);
|
||||
test_one_mulsi3(-10, 0, 0);
|
||||
test_one_mulsi3(0, minInt(i32), 0);
|
||||
test_one_mulsi3(minInt(i32), 0, 0);
|
||||
test_one_mulsi3(1, 1, 1);
|
||||
test_one_mulsi3(1, 10, 10);
|
||||
test_one_mulsi3(10, 1, 10);
|
||||
test_one_mulsi3(1, maxInt(i32), maxInt(i32));
|
||||
test_one_mulsi3(maxInt(i32), 1, maxInt(i32));
|
||||
test_one_mulsi3(1, -1, -1);
|
||||
test_one_mulsi3(1, -10, -10);
|
||||
test_one_mulsi3(-10, 1, -10);
|
||||
test_one_mulsi3(1, minInt(i32), minInt(i32));
|
||||
test_one_mulsi3(minInt(i32), 1, minInt(i32));
|
||||
test_one_mulsi3(46340, 46340, 2147395600);
|
||||
test_one_mulsi3(-46340, 46340, -2147395600);
|
||||
test_one_mulsi3(46340, -46340, -2147395600);
|
||||
test_one_mulsi3(-46340, -46340, 2147395600);
|
||||
test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176));
|
||||
test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176));
|
||||
test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176));
|
||||
test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176));
|
||||
test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176));
|
||||
test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176));
|
||||
test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176));
|
||||
test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
@ -108,12 +124,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,
|
||||
@ -129,8 +145,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,
|
||||
@ -143,10 +159,7 @@ pub const Target = union(enum) {
|
||||
v8_3a,
|
||||
v8_2a,
|
||||
v8_1a,
|
||||
v8,
|
||||
v8r,
|
||||
v8m_baseline,
|
||||
v8m_mainline,
|
||||
v8a,
|
||||
};
|
||||
pub const Kalimba = enum {
|
||||
v5,
|
||||
@ -160,6 +173,54 @@ pub const Target = union(enum) {
|
||||
spe,
|
||||
};
|
||||
|
||||
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,
|
||||
@ -188,6 +249,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,
|
||||
@ -300,6 +408,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 {
|
||||
@ -325,6 +536,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,
|
||||
@ -348,6 +662,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{
|
||||
@ -355,11 +691,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()),
|
||||
@ -425,14 +769,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,
|
||||
};
|
||||
@ -498,7 +846,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 {
|
||||
@ -819,3 +1167,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
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
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
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
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
76
lib/std/target/bpf.zig
Normal 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
312
lib/std/target/hexagon.zig
Normal 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
518
lib/std/target/mips.zig
Normal 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
72
lib/std/target/msp430.zig
Normal 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
309
lib/std/target/nvptx.zig
Normal 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
938
lib/std/target/powerpc.zig
Normal 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
122
lib/std/target/riscv.zig
Normal 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
495
lib/std/target/sparc.zig
Normal 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
510
lib/std/target/systemz.zig
Normal 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
114
lib/std/target/wasm.zig
Normal 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
2859
lib/std/target/x86.zig
Normal file
File diff suppressed because it is too large
Load Diff
@ -776,6 +776,7 @@ pub extern fn ZigClangFieldDecl_getCanonicalDecl(field_decl: ?*const struct_ZigC
|
||||
pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
|
||||
pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
|
||||
pub extern fn ZigClangParmVarDecl_getOriginalType(self: ?*const struct_ZigClangParmVarDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
|
||||
pub extern fn ZigClangVarDecl_getSectionAttribute(self: *const ZigClangVarDecl, len: *usize) ?[*]const u8;
|
||||
pub extern fn ZigClangFunctionDecl_getAlignedAttribute(self: *const ZigClangFunctionDecl, *const ZigClangASTContext) c_uint;
|
||||
@ -817,6 +818,7 @@ pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType
|
||||
pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
|
||||
pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;
|
||||
|
@ -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)});
|
||||
}
|
||||
|
251
src-self-hosted/print_targets.zig
Normal file
251
src-self-hosted/print_targets.zig
Normal 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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -443,12 +443,22 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
};
|
||||
|
||||
var fn_qt = ZigClangFunctionDecl_getType(fn_decl);
|
||||
var fn_type = ZigClangQualType_getTypePtr(fn_qt);
|
||||
if (ZigClangType_getTypeClass(fn_type) == .Attributed) {
|
||||
const attr_type = @ptrCast(*const ZigClangAttributedType, fn_type);
|
||||
fn_qt = ZigClangAttributedType_getEquivalentType(attr_type);
|
||||
fn_type = ZigClangQualType_getTypePtr(fn_qt);
|
||||
}
|
||||
|
||||
const fn_type = while (true) {
|
||||
const fn_type = ZigClangQualType_getTypePtr(fn_qt);
|
||||
|
||||
switch (ZigClangType_getTypeClass(fn_type)) {
|
||||
.Attributed => {
|
||||
const attr_type = @ptrCast(*const ZigClangAttributedType, fn_type);
|
||||
fn_qt = ZigClangAttributedType_getEquivalentType(attr_type);
|
||||
},
|
||||
.Paren => {
|
||||
const paren_type = @ptrCast(*const ZigClangParenType, fn_type);
|
||||
fn_qt = ZigClangParenType_getInnerType(paren_type);
|
||||
},
|
||||
else => break fn_type,
|
||||
}
|
||||
} else unreachable;
|
||||
|
||||
const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
|
||||
.FunctionProto => blk: {
|
||||
@ -485,6 +495,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
block_scope.block_node = block_node;
|
||||
|
||||
var it = proto_node.params.iterator(0);
|
||||
var param_id: c_uint = 0;
|
||||
while (it.next()) |p| {
|
||||
const param = @fieldParentPtr(ast.Node.ParamDecl, "base", p.*);
|
||||
const param_name = if (param.name_token) |name_tok|
|
||||
@ -498,18 +509,27 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
|
||||
const mangled_param_name = try block_scope.makeMangledName(c, param_name);
|
||||
|
||||
const c_param = ZigClangFunctionDecl_getParamDecl(fn_decl, param_id);
|
||||
const qual_type = ZigClangParmVarDecl_getOriginalType(c_param);
|
||||
const is_const = ZigClangQualType_isConstQualified(qual_type);
|
||||
|
||||
const arg_name = blk: {
|
||||
const bare_arg_name = try std.fmt.allocPrint(c.a(), "arg_{}", .{mangled_param_name});
|
||||
const param_prefix = if (is_const) "" else "arg_";
|
||||
const bare_arg_name = try std.fmt.allocPrint(c.a(), "{}{}", .{ param_prefix, mangled_param_name });
|
||||
break :blk try block_scope.makeMangledName(c, bare_arg_name);
|
||||
};
|
||||
|
||||
const node = try transCreateNodeVarDecl(c, false, false, mangled_param_name);
|
||||
node.eq_token = try appendToken(c, .Equal, "=");
|
||||
node.init_node = try transCreateNodeIdentifier(c, arg_name);
|
||||
node.semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
try block_node.statements.push(&node.base);
|
||||
param.name_token = try appendIdentifier(c, arg_name);
|
||||
_ = try appendToken(c, .Colon, ":");
|
||||
if (!is_const) {
|
||||
const node = try transCreateNodeVarDecl(c, false, false, mangled_param_name);
|
||||
node.eq_token = try appendToken(c, .Equal, "=");
|
||||
node.init_node = try transCreateNodeIdentifier(c, arg_name);
|
||||
node.semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
try block_node.statements.push(&node.base);
|
||||
param.name_token = try appendIdentifier(c, arg_name);
|
||||
_ = try appendToken(c, .Colon, ":");
|
||||
}
|
||||
|
||||
param_id += 1;
|
||||
}
|
||||
|
||||
transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) {
|
||||
@ -1982,7 +2002,8 @@ fn transInitListExprArray(
|
||||
const arr_type = ZigClangType_getAsArrayTypeUnsafe(ty);
|
||||
const child_qt = ZigClangArrayType_getElementType(arr_type);
|
||||
const init_count = ZigClangInitListExpr_getNumInits(expr);
|
||||
const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty);
|
||||
assert(ZigClangType_isConstantArrayType(@ptrCast(*const ZigClangType, arr_type)));
|
||||
const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, arr_type);
|
||||
const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
|
||||
const all_count = ZigClangAPInt_getLimitedValue(size_ap_int, math.maxInt(usize));
|
||||
const leftover_count = all_count - init_count;
|
||||
|
2336
src/all_types.hpp
2336
src/all_types.hpp
File diff suppressed because it is too large
Load Diff
401
src/analyze.cpp
401
src/analyze.cpp
@ -199,7 +199,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) {
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime) {
|
||||
ScopeRuntime *scope = allocate<ScopeRuntime>(1);
|
||||
scope->is_comptime = is_comptime;
|
||||
init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
|
||||
@ -593,9 +593,9 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
|
||||
}
|
||||
|
||||
if (inferred_struct_field != nullptr) {
|
||||
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
|
||||
entry->abi_align = g->builtin_types.entry_usize->abi_align;
|
||||
entry->abi_size = SIZE_MAX;
|
||||
entry->size_in_bits = SIZE_MAX;
|
||||
entry->abi_align = UINT32_MAX;
|
||||
} else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {
|
||||
if (type_has_bits(child_type)) {
|
||||
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||
@ -1102,11 +1102,28 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
|
||||
ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
|
||||
Buf *type_name, UndefAllowed undef)
|
||||
{
|
||||
Error err;
|
||||
|
||||
ZigValue *result = create_const_vals(1);
|
||||
ZigValue *result_ptr = create_const_vals(1);
|
||||
result->special = ConstValSpecialUndef;
|
||||
result->type = (type_entry == nullptr) ? g->builtin_types.entry_var : type_entry;
|
||||
result_ptr->special = ConstValSpecialStatic;
|
||||
result_ptr->type = get_pointer_to_type(g, result->type, false);
|
||||
result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar;
|
||||
result_ptr->data.x_ptr.special = ConstPtrSpecialRef;
|
||||
result_ptr->data.x_ptr.data.ref.pointee = result;
|
||||
|
||||
size_t backward_branch_count = 0;
|
||||
size_t backward_branch_quota = default_backward_branch_quota;
|
||||
return ir_eval_const_value(g, scope, node, type_entry,
|
||||
if ((err = ir_eval_const_value(g, scope, node, result_ptr,
|
||||
&backward_branch_count, &backward_branch_quota,
|
||||
nullptr, nullptr, node, type_name, nullptr, nullptr, undef);
|
||||
nullptr, nullptr, node, type_name, nullptr, nullptr, undef)))
|
||||
{
|
||||
return g->invalid_inst_gen->value;
|
||||
}
|
||||
destroy(result_ptr, "ZigValue");
|
||||
return result;
|
||||
}
|
||||
|
||||
Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent_type,
|
||||
@ -3350,7 +3367,7 @@ static void get_fully_qualified_decl_name(CodeGen *g, Buf *buf, Tld *tld, bool i
|
||||
|
||||
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
|
||||
ZigFn *fn_entry = allocate<ZigFn>(1, "ZigFn");
|
||||
fn_entry->ir_executable = allocate<IrExecutable>(1, "IrExecutablePass1");
|
||||
fn_entry->ir_executable = allocate<IrExecutableSrc>(1, "IrExecutableSrc");
|
||||
|
||||
fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
|
||||
|
||||
@ -3829,7 +3846,6 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
|
||||
variable_entry->var_type = var_type;
|
||||
variable_entry->parent_scope = parent_scope;
|
||||
variable_entry->shadowable = false;
|
||||
variable_entry->mem_slot_index = SIZE_MAX;
|
||||
variable_entry->src_arg_index = SIZE_MAX;
|
||||
|
||||
assert(name);
|
||||
@ -3930,7 +3946,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
|
||||
|
||||
// TODO more validation for types that can't be used for export/extern variables
|
||||
ZigType *implicit_type = nullptr;
|
||||
if (explicit_type && explicit_type->id == ZigTypeIdInvalid) {
|
||||
if (explicit_type != nullptr && explicit_type->id == ZigTypeIdInvalid) {
|
||||
implicit_type = explicit_type;
|
||||
} else if (var_decl->expr) {
|
||||
init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type,
|
||||
@ -4097,7 +4113,7 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco
|
||||
if (type_is_invalid(result->type)) {
|
||||
dest_decls_scope->any_imports_failed = true;
|
||||
using_namespace->base.resolution = TldResolutionInvalid;
|
||||
using_namespace->using_namespace_value = g->invalid_instruction->value;
|
||||
using_namespace->using_namespace_value = g->invalid_inst_gen->value;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4106,7 +4122,7 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco
|
||||
buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&result->data.x_type->name)));
|
||||
dest_decls_scope->any_imports_failed = true;
|
||||
using_namespace->base.resolution = TldResolutionInvalid;
|
||||
using_namespace->using_namespace_value = g->invalid_instruction->value;
|
||||
using_namespace->using_namespace_value = g->invalid_inst_gen->value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4667,12 +4683,12 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fn->call_list.length; i += 1) {
|
||||
IrInstructionCallGen *call = fn->call_list.at(i);
|
||||
IrInstGenCall *call = fn->call_list.at(i);
|
||||
if (call->fn_entry == nullptr) {
|
||||
// TODO function pointer call here, could be anything
|
||||
continue;
|
||||
}
|
||||
switch (analyze_callee_async(g, fn, call->fn_entry, call->base.source_node, must_not_be_async,
|
||||
switch (analyze_callee_async(g, fn, call->fn_entry, call->base.base.source_node, must_not_be_async,
|
||||
call->modifier))
|
||||
{
|
||||
case ErrorSemanticAnalyzeFail:
|
||||
@ -4690,10 +4706,10 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < fn->await_list.length; i += 1) {
|
||||
IrInstructionAwaitGen *await = fn->await_list.at(i);
|
||||
IrInstGenAwait *await = fn->await_list.at(i);
|
||||
// TODO If this is a noasync await, it doesn't count
|
||||
// https://github.com/ziglang/zig/issues/3157
|
||||
switch (analyze_callee_async(g, fn, await->target_fn, await->base.source_node, must_not_be_async,
|
||||
switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
|
||||
CallModifierNone))
|
||||
{
|
||||
case ErrorSemanticAnalyzeFail:
|
||||
@ -4718,8 +4734,14 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
|
||||
assert(!fn_type->data.fn.is_generic);
|
||||
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
|
||||
|
||||
if (fn->analyzed_executable.begin_scope == nullptr) {
|
||||
fn->analyzed_executable.begin_scope = &fn->def_scope->base;
|
||||
}
|
||||
if (fn->analyzed_executable.source_node == nullptr) {
|
||||
fn->analyzed_executable.source_node = fn->body_node;
|
||||
}
|
||||
ZigType *block_return_type = ir_analyze(g, fn->ir_executable,
|
||||
&fn->analyzed_executable, fn_type_id->return_type, return_type_node);
|
||||
&fn->analyzed_executable, fn_type_id->return_type, return_type_node, nullptr);
|
||||
fn->src_implicit_return_type = block_return_type;
|
||||
|
||||
if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {
|
||||
@ -4784,7 +4806,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
|
||||
|
||||
if (g->verbose_ir) {
|
||||
fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn->symbol_name));
|
||||
ir_print(g, stderr, &fn->analyzed_executable, 4, IrPassGen);
|
||||
ir_print_gen(g, stderr, &fn->analyzed_executable, 4);
|
||||
fprintf(stderr, "}\n");
|
||||
}
|
||||
fn->anal_state = FnAnalStateComplete;
|
||||
@ -4827,7 +4849,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
|
||||
fprintf(stderr, "\n");
|
||||
ast_render(stderr, fn_table_entry->body_node, 4);
|
||||
fprintf(stderr, "\nfn %s() { // (IR)\n", buf_ptr(&fn_table_entry->symbol_name));
|
||||
ir_print(g, stderr, fn_table_entry->ir_executable, 4, IrPassSrc);
|
||||
ir_print_src(g, stderr, fn_table_entry->ir_executable, 4);
|
||||
fprintf(stderr, "}\n");
|
||||
}
|
||||
|
||||
@ -5619,6 +5641,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
return OnePossibleValueYes;
|
||||
return type_has_one_possible_value(g, type_entry->data.array.child_type);
|
||||
case ZigTypeIdStruct:
|
||||
// If the recursive function call asks, then we are not one possible value.
|
||||
type_entry->one_possible_value = OnePossibleValueNo;
|
||||
for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
|
||||
TypeStructField *field = type_entry->data.structure.fields[i];
|
||||
OnePossibleValue opv = (field->type_entry != nullptr) ?
|
||||
@ -5626,6 +5650,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
type_val_resolve_has_one_possible_value(g, field->type_val);
|
||||
switch (opv) {
|
||||
case OnePossibleValueInvalid:
|
||||
type_entry->one_possible_value = OnePossibleValueInvalid;
|
||||
return OnePossibleValueInvalid;
|
||||
case OnePossibleValueNo:
|
||||
return OnePossibleValueNo;
|
||||
@ -5633,6 +5658,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
type_entry->one_possible_value = OnePossibleValueYes;
|
||||
return OnePossibleValueYes;
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
@ -5678,6 +5704,9 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
assert(field_type != nullptr);
|
||||
result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);
|
||||
}
|
||||
} else if (result->type->id == ZigTypeIdPointer) {
|
||||
result->data.x_ptr.special = ConstPtrSpecialRef;
|
||||
result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type);
|
||||
}
|
||||
g->one_possible_values.put(type_entry, result);
|
||||
return result;
|
||||
@ -6191,13 +6220,13 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
ZigType *fn_type = get_async_fn_type(g, fn->type_entry);
|
||||
|
||||
if (fn->analyzed_executable.need_err_code_spill) {
|
||||
IrInstructionAllocaGen *alloca_gen = allocate<IrInstructionAllocaGen>(1);
|
||||
alloca_gen->base.id = IrInstructionIdAllocaGen;
|
||||
alloca_gen->base.source_node = fn->proto_node;
|
||||
alloca_gen->base.scope = fn->child_scope;
|
||||
IrInstGenAlloca *alloca_gen = allocate<IrInstGenAlloca>(1);
|
||||
alloca_gen->base.id = IrInstGenIdAlloca;
|
||||
alloca_gen->base.base.source_node = fn->proto_node;
|
||||
alloca_gen->base.base.scope = fn->child_scope;
|
||||
alloca_gen->base.value = allocate<ZigValue>(1, "ZigValue");
|
||||
alloca_gen->base.value->type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
|
||||
alloca_gen->base.ref_count = 1;
|
||||
alloca_gen->base.base.ref_count = 1;
|
||||
alloca_gen->name_hint = "";
|
||||
fn->alloca_gen_list.append(alloca_gen);
|
||||
fn->err_code_spill = &alloca_gen->base;
|
||||
@ -6205,18 +6234,18 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
|
||||
ZigType *largest_call_frame_type = nullptr;
|
||||
// Later we'll change this to be largest_call_frame_type instead of void.
|
||||
IrInstruction *all_calls_alloca = ir_create_alloca(g, &fn->fndef_scope->base, fn->body_node,
|
||||
IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn->fndef_scope->base, fn->body_node,
|
||||
fn, g->builtin_types.entry_void, "@async_call_frame");
|
||||
|
||||
for (size_t i = 0; i < fn->call_list.length; i += 1) {
|
||||
IrInstructionCallGen *call = fn->call_list.at(i);
|
||||
IrInstGenCall *call = fn->call_list.at(i);
|
||||
if (call->new_stack != nullptr) {
|
||||
// don't need to allocate a frame for this
|
||||
continue;
|
||||
}
|
||||
ZigFn *callee = call->fn_entry;
|
||||
if (callee == nullptr) {
|
||||
add_node_error(g, call->base.source_node,
|
||||
add_node_error(g, call->base.base.source_node,
|
||||
buf_sprintf("function is not comptime-known; @asyncCall required"));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
@ -6226,14 +6255,14 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
if (callee->anal_state == FnAnalStateProbing) {
|
||||
ErrorMsg *msg = add_node_error(g, fn->proto_node,
|
||||
buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
|
||||
g->trace_err = add_error_note(g, msg, call->base.source_node,
|
||||
g->trace_err = add_error_note(g, msg, call->base.base.source_node,
|
||||
buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
|
||||
ZigType *callee_frame_type = get_fn_frame_type(g, callee);
|
||||
frame_type->data.frame.resolve_loop_type = callee_frame_type;
|
||||
frame_type->data.frame.resolve_loop_src_node = call->base.source_node;
|
||||
frame_type->data.frame.resolve_loop_src_node = call->base.base.source_node;
|
||||
|
||||
analyze_fn_body(g, callee);
|
||||
if (callee->anal_state == FnAnalStateInvalid) {
|
||||
@ -6249,7 +6278,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
if (!fn_is_async(callee))
|
||||
continue;
|
||||
|
||||
mark_suspension_point(call->base.scope);
|
||||
mark_suspension_point(call->base.base.scope);
|
||||
|
||||
if ((err = type_resolve(g, callee_frame_type, ResolveStatusSizeKnown))) {
|
||||
return err;
|
||||
@ -6271,7 +6300,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
// For example: foo() + await z
|
||||
// The funtion call result of foo() must be spilled.
|
||||
for (size_t i = 0; i < fn->await_list.length; i += 1) {
|
||||
IrInstructionAwaitGen *await = fn->await_list.at(i);
|
||||
IrInstGenAwait *await = fn->await_list.at(i);
|
||||
// TODO If this is a noasync await, it doesn't suspend
|
||||
// https://github.com/ziglang/zig/issues/3157
|
||||
if (await->base.value->special != ConstValSpecialRuntime) {
|
||||
@ -6293,52 +6322,51 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
}
|
||||
// This await is a suspend point, but it might not need a spill.
|
||||
// We do need to mark the ExprScope as having a suspend point in it.
|
||||
mark_suspension_point(await->base.scope);
|
||||
mark_suspension_point(await->base.base.scope);
|
||||
|
||||
if (await->result_loc != nullptr) {
|
||||
// If there's a result location, that is the spill
|
||||
continue;
|
||||
}
|
||||
if (await->base.ref_count == 0)
|
||||
if (await->base.base.ref_count == 0)
|
||||
continue;
|
||||
if (!type_has_bits(await->base.value->type))
|
||||
continue;
|
||||
await->result_loc = ir_create_alloca(g, await->base.scope, await->base.source_node, fn,
|
||||
await->result_loc = ir_create_alloca(g, await->base.base.scope, await->base.base.source_node, fn,
|
||||
await->base.value->type, "");
|
||||
}
|
||||
for (size_t block_i = 0; block_i < fn->analyzed_executable.basic_block_list.length; block_i += 1) {
|
||||
IrBasicBlock *block = fn->analyzed_executable.basic_block_list.at(block_i);
|
||||
IrBasicBlockGen *block = fn->analyzed_executable.basic_block_list.at(block_i);
|
||||
for (size_t instr_i = 0; instr_i < block->instruction_list.length; instr_i += 1) {
|
||||
IrInstruction *instruction = block->instruction_list.at(instr_i);
|
||||
if (instruction->id == IrInstructionIdSuspendFinish) {
|
||||
mark_suspension_point(instruction->scope);
|
||||
IrInstGen *instruction = block->instruction_list.at(instr_i);
|
||||
if (instruction->id == IrInstGenIdSuspendFinish) {
|
||||
mark_suspension_point(instruction->base.scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now that we've marked all the expr scopes that have to spill, we go over the instructions
|
||||
// and spill the relevant ones.
|
||||
for (size_t block_i = 0; block_i < fn->analyzed_executable.basic_block_list.length; block_i += 1) {
|
||||
IrBasicBlock *block = fn->analyzed_executable.basic_block_list.at(block_i);
|
||||
IrBasicBlockGen *block = fn->analyzed_executable.basic_block_list.at(block_i);
|
||||
for (size_t instr_i = 0; instr_i < block->instruction_list.length; instr_i += 1) {
|
||||
IrInstruction *instruction = block->instruction_list.at(instr_i);
|
||||
if (instruction->id == IrInstructionIdAwaitGen ||
|
||||
instruction->id == IrInstructionIdVarPtr ||
|
||||
instruction->id == IrInstructionIdDeclRef ||
|
||||
instruction->id == IrInstructionIdAllocaGen)
|
||||
IrInstGen *instruction = block->instruction_list.at(instr_i);
|
||||
if (instruction->id == IrInstGenIdAwait ||
|
||||
instruction->id == IrInstGenIdVarPtr ||
|
||||
instruction->id == IrInstGenIdAlloca)
|
||||
{
|
||||
// This instruction does its own spilling specially, or otherwise doesn't need it.
|
||||
continue;
|
||||
}
|
||||
if (instruction->value->special != ConstValSpecialRuntime)
|
||||
continue;
|
||||
if (instruction->ref_count == 0)
|
||||
if (instruction->base.ref_count == 0)
|
||||
continue;
|
||||
if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown)))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
if (!type_has_bits(instruction->value->type))
|
||||
continue;
|
||||
if (scope_needs_spill(instruction->scope)) {
|
||||
instruction->spill = ir_create_alloca(g, instruction->scope, instruction->source_node,
|
||||
if (scope_needs_spill(instruction->base.scope)) {
|
||||
instruction->spill = ir_create_alloca(g, instruction->base.scope, instruction->base.source_node,
|
||||
fn, instruction->value->type, "");
|
||||
}
|
||||
}
|
||||
@ -6389,14 +6417,14 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
}
|
||||
|
||||
for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
|
||||
IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);
|
||||
IrInstGenAlloca *instruction = fn->alloca_gen_list.at(alloca_i);
|
||||
instruction->field_index = SIZE_MAX;
|
||||
ZigType *ptr_type = instruction->base.value->type;
|
||||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
ZigType *child_type = ptr_type->data.pointer.child_type;
|
||||
if (!type_has_bits(child_type))
|
||||
continue;
|
||||
if (instruction->base.ref_count == 0)
|
||||
if (instruction->base.base.ref_count == 0)
|
||||
continue;
|
||||
if (instruction->base.value->special != ConstValSpecialRuntime) {
|
||||
if (const_ptr_pointee(nullptr, g, instruction->base.value, nullptr)->special !=
|
||||
@ -6407,7 +6435,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
}
|
||||
|
||||
frame_type->data.frame.resolve_loop_type = child_type;
|
||||
frame_type->data.frame.resolve_loop_src_node = instruction->base.source_node;
|
||||
frame_type->data.frame.resolve_loop_src_node = instruction->base.base.source_node;
|
||||
if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) {
|
||||
return err;
|
||||
}
|
||||
@ -6421,7 +6449,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
||||
instruction->field_index = fields.length;
|
||||
|
||||
src_assert(child_type->id != ZigTypeIdPointer || child_type->data.pointer.inferred_struct_field == nullptr,
|
||||
instruction->base.source_node);
|
||||
instruction->base.base.source_node);
|
||||
fields.append({name, child_type, instruction->align});
|
||||
}
|
||||
|
||||
@ -6453,7 +6481,21 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {
|
||||
}
|
||||
ty->data.pointer.resolve_loop_flag_zero_bits = true;
|
||||
|
||||
ZigType *elem_type = ty->data.pointer.child_type;
|
||||
ZigType *elem_type;
|
||||
InferredStructField *isf = ty->data.pointer.inferred_struct_field;
|
||||
if (isf != nullptr) {
|
||||
TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
|
||||
assert(field != nullptr);
|
||||
if (field->is_comptime) {
|
||||
ty->abi_size = 0;
|
||||
ty->size_in_bits = 0;
|
||||
ty->abi_align = 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
elem_type = field->type_entry;
|
||||
} else {
|
||||
elem_type = ty->data.pointer.child_type;
|
||||
}
|
||||
|
||||
bool has_bits;
|
||||
if ((err = type_has_bits2(g, elem_type, &has_bits)))
|
||||
@ -6554,8 +6596,10 @@ bool ir_get_var_is_comptime(ZigVar *var) {
|
||||
// As an optimization, is_comptime values which are constant are allowed
|
||||
// to be omitted from analysis. In this case, there is no child instruction
|
||||
// and we simply look at the unanalyzed const parent instruction.
|
||||
assert(var->is_comptime->value->type->id == ZigTypeIdBool);
|
||||
var->is_comptime_memoized_value = var->is_comptime->value->data.x_bool;
|
||||
assert(var->is_comptime->id == IrInstSrcIdConst);
|
||||
IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(var->is_comptime);
|
||||
assert(const_inst->value->type->id == ZigTypeIdBool);
|
||||
var->is_comptime_memoized_value = const_inst->value->data.x_bool;
|
||||
var->is_comptime = nullptr;
|
||||
return var->is_comptime_memoized_value;
|
||||
}
|
||||
@ -6874,6 +6918,7 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu
|
||||
}
|
||||
case ConstArraySpecialNone: {
|
||||
ZigValue *base = &array->data.s_none.elements[start];
|
||||
assert(base != nullptr);
|
||||
assert(start + len <= const_val->type->data.array.len);
|
||||
|
||||
buf_appendf(buf, "%s{", buf_ptr(type_name));
|
||||
@ -6889,6 +6934,10 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu
|
||||
}
|
||||
|
||||
void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) {
|
||||
if (const_val == nullptr) {
|
||||
buf_appendf(buf, "(invalid nullptr value)");
|
||||
return;
|
||||
}
|
||||
switch (const_val->special) {
|
||||
case ConstValSpecialRuntime:
|
||||
buf_appendf(buf, "(runtime value)");
|
||||
@ -9193,21 +9242,6 @@ void src_assert(bool ok, AstNode *source_node) {
|
||||
stage2_panic(msg, strlen(msg));
|
||||
}
|
||||
|
||||
IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
|
||||
ZigType *var_type, const char *name_hint)
|
||||
{
|
||||
IrInstructionAllocaGen *alloca_gen = allocate<IrInstructionAllocaGen>(1);
|
||||
alloca_gen->base.id = IrInstructionIdAllocaGen;
|
||||
alloca_gen->base.source_node = source_node;
|
||||
alloca_gen->base.scope = scope;
|
||||
alloca_gen->base.value = allocate<ZigValue>(1, "ZigValue");
|
||||
alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false);
|
||||
alloca_gen->base.ref_count = 1;
|
||||
alloca_gen->name_hint = name_hint;
|
||||
fn->alloca_gen_list.append(alloca_gen);
|
||||
return &alloca_gen->base;
|
||||
}
|
||||
|
||||
Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
|
||||
ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path)
|
||||
{
|
||||
@ -9268,8 +9302,17 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
|
||||
}
|
||||
|
||||
|
||||
void IrExecutable::src() {
|
||||
IrExecutable *it;
|
||||
void IrExecutableSrc::src() {
|
||||
if (this->source_node != nullptr) {
|
||||
this->source_node->src();
|
||||
}
|
||||
if (this->parent_exec != nullptr) {
|
||||
this->parent_exec->src();
|
||||
}
|
||||
}
|
||||
|
||||
void IrExecutableGen::src() {
|
||||
IrExecutableGen *it;
|
||||
for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) {
|
||||
it->source_node->src();
|
||||
}
|
||||
@ -9300,10 +9343,13 @@ bool type_has_optional_repr(ZigType *ty) {
|
||||
}
|
||||
|
||||
void copy_const_val(ZigValue *dest, ZigValue *src) {
|
||||
uint32_t prev_align = dest->llvm_align;
|
||||
ConstParent prev_parent = dest->parent;
|
||||
memcpy(dest, src, sizeof(ZigValue));
|
||||
dest->llvm_align = prev_align;
|
||||
if (src->special != ConstValSpecialStatic)
|
||||
return;
|
||||
dest->parent.id = ConstParentIdNone;
|
||||
dest->parent = prev_parent;
|
||||
if (dest->type->id == ZigTypeIdStruct) {
|
||||
dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
|
||||
for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
|
||||
@ -9312,6 +9358,16 @@ void copy_const_val(ZigValue *dest, ZigValue *src) {
|
||||
dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;
|
||||
dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
|
||||
}
|
||||
} else if (dest->type->id == ZigTypeIdArray) {
|
||||
if (dest->data.x_array.special == ConstArraySpecialNone) {
|
||||
dest->data.x_array.data.s_none.elements = create_const_vals(dest->type->data.array.len);
|
||||
for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {
|
||||
copy_const_val(&dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
|
||||
dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;
|
||||
dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;
|
||||
dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;
|
||||
}
|
||||
}
|
||||
} else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
|
||||
dest->data.x_optional = create_const_vals(1);
|
||||
copy_const_val(dest->data.x_optional, src->data.x_optional);
|
||||
@ -9357,3 +9413,206 @@ bool type_is_numeric(ZigType *ty) {
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void dump_value_indent(ZigValue *val, int indent) {
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "Value@%p(", val);
|
||||
if (val->type != nullptr) {
|
||||
fprintf(stderr, "%s)", buf_ptr(&val->type->name));
|
||||
} else {
|
||||
fprintf(stderr, "type=nullptr)");
|
||||
}
|
||||
switch (val->special) {
|
||||
case ConstValSpecialUndef:
|
||||
fprintf(stderr, "[undefined]\n");
|
||||
return;
|
||||
case ConstValSpecialLazy:
|
||||
fprintf(stderr, "[lazy]\n");
|
||||
return;
|
||||
case ConstValSpecialRuntime:
|
||||
fprintf(stderr, "[runtime]\n");
|
||||
return;
|
||||
case ConstValSpecialStatic:
|
||||
break;
|
||||
}
|
||||
if (val->type == nullptr)
|
||||
return;
|
||||
switch (val->type->id) {
|
||||
case ZigTypeIdInvalid:
|
||||
fprintf(stderr, "<invalid>\n");
|
||||
return;
|
||||
case ZigTypeIdUnreachable:
|
||||
fprintf(stderr, "<unreachable>\n");
|
||||
return;
|
||||
case ZigTypeIdUndefined:
|
||||
fprintf(stderr, "<undefined>\n");
|
||||
return;
|
||||
case ZigTypeIdVoid:
|
||||
fprintf(stderr, "<{}>\n");
|
||||
return;
|
||||
case ZigTypeIdMetaType:
|
||||
fprintf(stderr, "<%s>\n", buf_ptr(&val->data.x_type->name));
|
||||
return;
|
||||
case ZigTypeIdBool:
|
||||
fprintf(stderr, "<%s>\n", val->data.x_bool ? "true" : "false");
|
||||
return;
|
||||
case ZigTypeIdComptimeInt:
|
||||
case ZigTypeIdInt: {
|
||||
Buf *tmp_buf = buf_alloc();
|
||||
bigint_append_buf(tmp_buf, &val->data.x_bigint, 10);
|
||||
fprintf(stderr, "<%s>\n", buf_ptr(tmp_buf));
|
||||
buf_destroy(tmp_buf);
|
||||
return;
|
||||
}
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdFloat:
|
||||
fprintf(stderr, "<TODO dump number>\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdStruct:
|
||||
fprintf(stderr, "<struct\n");
|
||||
for (size_t i = 0; i < val->type->data.structure.src_field_count; i += 1) {
|
||||
for (int j = 0; j < indent; j += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "%s: ", buf_ptr(val->type->data.structure.fields[i]->name));
|
||||
if (val->data.x_struct.fields == nullptr) {
|
||||
fprintf(stderr, "<null>\n");
|
||||
} else {
|
||||
dump_value_indent(val->data.x_struct.fields[i], 1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdOptional:
|
||||
fprintf(stderr, "<\n");
|
||||
dump_value_indent(val->data.x_optional, indent + 1);
|
||||
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdErrorUnion:
|
||||
if (val->data.x_err_union.payload != nullptr) {
|
||||
fprintf(stderr, "<\n");
|
||||
dump_value_indent(val->data.x_err_union.payload, indent + 1);
|
||||
} else {
|
||||
fprintf(stderr, "<\n");
|
||||
dump_value_indent(val->data.x_err_union.error_set, 0);
|
||||
}
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdPointer:
|
||||
switch (val->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
fprintf(stderr, "<!invalid ptr!>\n");
|
||||
return;
|
||||
case ConstPtrSpecialRef:
|
||||
fprintf(stderr, "<ref\n");
|
||||
dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1);
|
||||
break;
|
||||
case ConstPtrSpecialBaseStruct: {
|
||||
ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val;
|
||||
size_t field_index = val->data.x_ptr.data.base_struct.field_index;
|
||||
fprintf(stderr, "<struct %p field %zu\n", struct_val, field_index);
|
||||
if (struct_val != nullptr) {
|
||||
ZigValue *field_val = struct_val->data.x_struct.fields[field_index];
|
||||
if (field_val != nullptr) {
|
||||
dump_value_indent(field_val, indent + 1);
|
||||
} else {
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "(invalid null field)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConstPtrSpecialBaseOptionalPayload: {
|
||||
ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val;
|
||||
fprintf(stderr, "<optional %p payload\n", optional_val);
|
||||
if (optional_val != nullptr) {
|
||||
dump_value_indent(optional_val, indent + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "TODO dump more pointer things\n");
|
||||
}
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdArray:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
case ZigTypeIdEnumLiteral:
|
||||
fprintf(stderr, "<TODO dump value>\n");
|
||||
return;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
void ZigValue::dump() {
|
||||
dump_value_indent(this, 0);
|
||||
}
|
||||
|
||||
// float ops that take a single argument
|
||||
//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, lround, llround, lrint, llrint
|
||||
const char *float_op_to_name(BuiltinFnId op) {
|
||||
switch (op) {
|
||||
case BuiltinFnIdSqrt:
|
||||
return "sqrt";
|
||||
case BuiltinFnIdSin:
|
||||
return "sin";
|
||||
case BuiltinFnIdCos:
|
||||
return "cos";
|
||||
case BuiltinFnIdExp:
|
||||
return "exp";
|
||||
case BuiltinFnIdExp2:
|
||||
return "exp2";
|
||||
case BuiltinFnIdLog:
|
||||
return "log";
|
||||
case BuiltinFnIdLog10:
|
||||
return "log10";
|
||||
case BuiltinFnIdLog2:
|
||||
return "log2";
|
||||
case BuiltinFnIdFabs:
|
||||
return "fabs";
|
||||
case BuiltinFnIdFloor:
|
||||
return "floor";
|
||||
case BuiltinFnIdCeil:
|
||||
return "ceil";
|
||||
case BuiltinFnIdTrunc:
|
||||
return "trunc";
|
||||
case BuiltinFnIdNearbyInt:
|
||||
return "nearbyint";
|
||||
case BuiltinFnIdRound:
|
||||
return "round";
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
|
||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
|
||||
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
|
||||
@ -271,8 +271,6 @@ ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field);
|
||||
|
||||
void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn);
|
||||
|
||||
IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
|
||||
ZigType *var_type, const char *name_hint);
|
||||
Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str,
|
||||
ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
|
||||
ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry);
|
||||
@ -281,4 +279,5 @@ void copy_const_val(ZigValue *dest, ZigValue *src);
|
||||
bool type_has_optional_repr(ZigType *ty);
|
||||
bool is_opt_err_set(ZigType *ty);
|
||||
bool type_is_numeric(ZigType *ty);
|
||||
const char *float_op_to_name(BuiltinFnId op);
|
||||
#endif
|
||||
|
1056
src/codegen.cpp
1056
src/codegen.cpp
File diff suppressed because it is too large
Load Diff
@ -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)";
|
||||
}
|
||||
|
14637
src/ir.cpp
14637
src/ir.cpp
File diff suppressed because it is too large
Load Diff
26
src/ir.hpp
26
src/ir.hpp
@ -10,33 +10,33 @@
|
||||
|
||||
#include "all_types.hpp"
|
||||
|
||||
enum IrPass {
|
||||
IrPassSrc,
|
||||
IrPassGen,
|
||||
};
|
||||
|
||||
bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_executable);
|
||||
bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable);
|
||||
bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
|
||||
|
||||
ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
|
||||
ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
|
||||
IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
|
||||
ZigType *var_type, const char *name_hint);
|
||||
|
||||
Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
|
||||
ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,
|
||||
ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
|
||||
IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef);
|
||||
IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef);
|
||||
|
||||
Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val);
|
||||
|
||||
ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
|
||||
ZigType *expected_type, AstNode *expected_type_source_node);
|
||||
ZigType *ir_analyze(CodeGen *g, IrExecutableSrc *old_executable, IrExecutableGen *new_executable,
|
||||
ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *return_ptr);
|
||||
|
||||
bool ir_has_side_effects(IrInstruction *instruction);
|
||||
bool ir_inst_gen_has_side_effects(IrInstGen *inst);
|
||||
bool ir_inst_src_has_side_effects(IrInstSrc *inst);
|
||||
|
||||
struct IrAnalyze;
|
||||
ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
|
||||
AstNode *source_node);
|
||||
const char *float_op_to_name(BuiltinFnId op);
|
||||
|
||||
// for debugging purposes
|
||||
void dbg_ir_break(const char *src_file, uint32_t line);
|
||||
void dbg_ir_clear(void);
|
||||
|
||||
void destroy_instruction_gen(IrInstGen *inst);
|
||||
|
||||
#endif
|
||||
|
3389
src/ir_print.cpp
3389
src/ir_print.cpp
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,14 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);
|
||||
void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);
|
||||
void ir_print_const_expr(CodeGen *codegen, FILE *f, ZigValue *value, int indent_size, IrPass pass);
|
||||
void ir_print_basic_block(CodeGen *codegen, FILE *f, IrBasicBlock *bb, int indent_size, IrPass pass);
|
||||
void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int indent_size);
|
||||
void ir_print_gen(CodeGen *codegen, FILE *f, IrExecutableGen *executable, int indent_size);
|
||||
void ir_print_inst_src(CodeGen *codegen, FILE *f, IrInstSrc *inst, int indent_size);
|
||||
void ir_print_inst_gen(CodeGen *codegen, FILE *f, IrInstGen *inst, int indent_size);
|
||||
void ir_print_basic_block_src(CodeGen *codegen, FILE *f, IrBasicBlockSrc *bb, int indent_size);
|
||||
void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, int indent_size);
|
||||
|
||||
const char* ir_instruction_type_str(IrInstructionId id);
|
||||
const char* ir_inst_src_type_str(IrInstSrcId id);
|
||||
const char* ir_inst_gen_type_str(IrInstGenId id);
|
||||
|
||||
#endif
|
||||
|
13
src/link.cpp
13
src/link.cpp
@ -1502,6 +1502,19 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
|
||||
new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly;
|
||||
}
|
||||
|
||||
// Override the inherited build mode parameter
|
||||
if (!parent_gen->is_test_build) {
|
||||
switch (parent_gen->build_mode) {
|
||||
case BuildModeDebug:
|
||||
case BuildModeFastRelease:
|
||||
case BuildModeSafeRelease:
|
||||
child_gen->build_mode = BuildModeFastRelease;
|
||||
break;
|
||||
case BuildModeSmallRelease:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
child_gen->function_sections = true;
|
||||
child_gen->want_stack_check = WantStackCheckDisabled;
|
||||
|
||||
|
143
src/main.cpp
143
src/main.cpp
@ -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,11 @@ 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"
|
||||
" -code-model [default|tiny| set target code model\n"
|
||||
" small|kernel|\n"
|
||||
" medium|large]\n"
|
||||
"\n"
|
||||
"Link Options:\n"
|
||||
" --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
|
||||
@ -141,100 +147,18 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
|
||||
"You can save this into a file and then edit the paths to create a cross\n"
|
||||
"compilation libc kit. Then you can pass `--libc [file]` for Zig to use it.\n"
|
||||
"\n"
|
||||
"When compiling natively and no `--libc` argument provided, Zig automatically\n"
|
||||
"creates zig-cache/native_libc.txt so that it does not have to detect libc\n"
|
||||
"on every invocation. You can remove this file to have Zig re-detect the\n"
|
||||
"native libc.\n"
|
||||
"When compiling natively and no `--libc` argument provided, Zig will create\n"
|
||||
"`%s/native_libc.txt`\n"
|
||||
"so that it does not have to detect libc on every invocation. You can remove\n"
|
||||
"this file to have Zig re-detect the native libc.\n"
|
||||
"\n\n"
|
||||
"Usage: %s libc [file]\n"
|
||||
"\n"
|
||||
"Parse a libc installation text file and validate it.\n"
|
||||
, arg0, arg0);
|
||||
, arg0, buf_ptr(get_global_cache_dir()), arg0);
|
||||
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 +402,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 +453,9 @@ 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;
|
||||
CodeModel code_model = CodeModelDefault;
|
||||
|
||||
ZigList<const char *> llvm_argv = {0};
|
||||
llvm_argv.append("zig (LLVM option parsing)");
|
||||
@ -692,6 +620,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) {
|
||||
@ -842,6 +772,23 @@ int main(int argc, char **argv) {
|
||||
clang_argv.append(argv[i]);
|
||||
|
||||
llvm_argv.append(argv[i]);
|
||||
} else if (strcmp(arg, "-code-model") == 0) {
|
||||
if (strcmp(argv[i], "default") == 0) {
|
||||
code_model = CodeModelDefault;
|
||||
} else if (strcmp(argv[i], "tiny") == 0) {
|
||||
code_model = CodeModelTiny;
|
||||
} else if (strcmp(argv[i], "small") == 0) {
|
||||
code_model = CodeModelSmall;
|
||||
} else if (strcmp(argv[i], "kernel") == 0) {
|
||||
code_model = CodeModelKernel;
|
||||
} else if (strcmp(argv[i], "medium") == 0) {
|
||||
code_model = CodeModelMedium;
|
||||
} else if (strcmp(argv[i], "large") == 0) {
|
||||
code_model = CodeModelLarge;
|
||||
} else {
|
||||
fprintf(stderr, "-code-model options are 'default', 'tiny', 'small', 'kernel', 'medium', or 'large'\n");
|
||||
return print_error_usage(arg0);
|
||||
}
|
||||
} else if (strcmp(arg, "--override-lib-dir") == 0) {
|
||||
override_lib_dir = buf_create_from_str(argv[i]);
|
||||
} else if (strcmp(arg, "--main-pkg-path") == 0) {
|
||||
@ -936,6 +883,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 +1002,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,12 +1184,15 @@ 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;
|
||||
codegen_set_errmsg_color(g, color);
|
||||
g->system_linker_hack = system_linker_hack;
|
||||
g->function_sections = function_sections;
|
||||
g->code_model = code_model;
|
||||
|
||||
|
||||
for (size_t i = 0; i < lib_dirs.length; i += 1) {
|
||||
codegen_add_lib_dir(g, lib_dirs.at(i));
|
||||
@ -1413,7 +1374,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);
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ static void ast_invalid_token_error(ParseContext *pc, Token *token) {
|
||||
}
|
||||
|
||||
static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
|
||||
AstNode *node = allocate<AstNode>(1);
|
||||
AstNode *node = allocate<AstNode>(1, "AstNode");
|
||||
node->type = type;
|
||||
node->owner = pc->owner;
|
||||
return node;
|
||||
|
@ -12,4 +12,21 @@ extern "C" {
|
||||
#include "softfloat.h"
|
||||
}
|
||||
|
||||
static inline float16_t zig_double_to_f16(double x) {
|
||||
float64_t y;
|
||||
static_assert(sizeof(x) == sizeof(y), "");
|
||||
memcpy(&y, &x, sizeof(x));
|
||||
return f64_to_f16(y);
|
||||
}
|
||||
|
||||
|
||||
// Return value is safe to coerce to float even when |x| is NaN or Infinity.
|
||||
static inline double zig_f16_to_double(float16_t x) {
|
||||
float64_t y = f16_to_f64(x);
|
||||
double z;
|
||||
static_assert(sizeof(y) == sizeof(z), "");
|
||||
memcpy(&z, &y, sizeof(y));
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -58,9 +58,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[] = {
|
||||
@ -693,7 +690,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:
|
||||
@ -703,7 +700,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:
|
||||
@ -846,10 +843,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) {
|
||||
|
@ -92,6 +92,7 @@ struct ZigTarget {
|
||||
Os os;
|
||||
ZigLLVM_EnvironmentType abi;
|
||||
ZigGLibCVersion *glibc_version; // null means default
|
||||
Stage2CpuFeatures *cpu_features;
|
||||
bool is_native;
|
||||
};
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
21
src/util.hpp
21
src/util.hpp
@ -38,6 +38,8 @@
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define BREAKPOINT __debugbreak()
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
#define BREAKPOINT __asm__ volatile("int $0x03");
|
||||
#elif defined(__clang__)
|
||||
#define BREAKPOINT __builtin_debugtrap()
|
||||
#elif defined(__GNUC__)
|
||||
@ -49,8 +51,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "softfloat.hpp"
|
||||
|
||||
ATTRIBUTE_COLD
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(1, 2)
|
||||
@ -244,23 +244,6 @@ static inline uint8_t log2_u64(uint64_t x) {
|
||||
return (63 - clzll(x));
|
||||
}
|
||||
|
||||
static inline float16_t zig_double_to_f16(double x) {
|
||||
float64_t y;
|
||||
static_assert(sizeof(x) == sizeof(y), "");
|
||||
memcpy(&y, &x, sizeof(x));
|
||||
return f64_to_f16(y);
|
||||
}
|
||||
|
||||
|
||||
// Return value is safe to coerce to float even when |x| is NaN or Infinity.
|
||||
static inline double zig_f16_to_double(float16_t x) {
|
||||
float64_t y = f16_to_f64(x);
|
||||
double z;
|
||||
static_assert(sizeof(y) == sizeof(z), "");
|
||||
memcpy(&z, &y, sizeof(y));
|
||||
return z;
|
||||
}
|
||||
|
||||
void zig_pretty_print_bytes(FILE *f, double n);
|
||||
|
||||
template<typename T>
|
||||
|
@ -1668,6 +1668,10 @@ unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionD
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self) {
|
||||
return bitcast(reinterpret_cast<const clang::ParmVarDecl *>(self)->getOriginalType());
|
||||
}
|
||||
|
||||
const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
|
||||
const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
|
||||
const clang::RecordDecl *definition = record_decl->getDefinition();
|
||||
@ -1920,6 +1924,11 @@ bool ZigClangType_isRecordType(const ZigClangType *self) {
|
||||
return casted->isRecordType();
|
||||
}
|
||||
|
||||
bool ZigClangType_isConstantArrayType(const ZigClangType *self) {
|
||||
auto casted = reinterpret_cast<const clang::Type *>(self);
|
||||
return casted->isConstantArrayType();
|
||||
}
|
||||
|
||||
const char *ZigClangType_getTypeClassName(const ZigClangType *self) {
|
||||
auto casted = reinterpret_cast<const clang::Type *>(self);
|
||||
return casted->getTypeClassName();
|
||||
|
@ -886,6 +886,8 @@ ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigCla
|
||||
ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx);
|
||||
ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx);
|
||||
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self);
|
||||
|
||||
ZIG_EXTERN_C bool ZigClangRecordDecl_getPackedAttribute(const struct ZigClangRecordDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
|
||||
@ -965,6 +967,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self);
|
||||
ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self);
|
||||
ZIG_EXTERN_C const ZigClangRecordType *ZigClangType_getAsRecordType(const ZigClangType *self);
|
||||
|
@ -824,7 +824,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:
|
||||
@ -834,7 +834,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:
|
||||
|
@ -1,7 +1,14 @@
|
||||
const tests = @import("tests.zig");
|
||||
const builtin = @import("builtin");
|
||||
const Target = @import("std").Target;
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.addTest("dependency loop in top-level decl with @TypeInfo",
|
||||
\\export const foo = @typeInfo(@This());
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:1:20: error: dependency loop detected",
|
||||
});
|
||||
|
||||
cases.addTest("non-exhaustive enums",
|
||||
\\const A = enum {
|
||||
\\ a,
|
||||
@ -272,9 +279,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 +681,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,
|
||||
},
|
||||
@ -1649,7 +1658,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.addTest("return invalid type from test",
|
||||
\\test "example" { return 1; }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:1:25: error: integer value 1 cannot be coerced to type 'void'",
|
||||
"tmp.zig:1:25: error: expected type 'void', found 'comptime_int'",
|
||||
});
|
||||
|
||||
cases.add("threadlocal qualifier on const",
|
||||
@ -2478,7 +2487,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ var rule_set = try Foo.init();
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:2:10: error: expected type 'i32', found 'type'",
|
||||
"tmp.zig:2:19: error: expected type 'i32', found 'type'",
|
||||
});
|
||||
|
||||
cases.add("slicing single-item pointer",
|
||||
@ -3384,7 +3393,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\
|
||||
\\fn b() void {}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:3:6: error: unreachable code",
|
||||
"tmp.zig:3:5: error: unreachable code",
|
||||
});
|
||||
|
||||
cases.add("bad import",
|
||||
@ -4002,8 +4011,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\
|
||||
\\export fn entry() usize { return @sizeOf(@TypeOf(Foo)); }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:5:25: error: unable to evaluate constant expression",
|
||||
"tmp.zig:2:12: note: referenced here",
|
||||
"tmp.zig:5:25: error: cannot store runtime value in compile time variable",
|
||||
"tmp.zig:2:12: note: called from here",
|
||||
});
|
||||
|
||||
cases.add("addition with non numbers",
|
||||
@ -4643,7 +4652,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\fn something() anyerror!void { }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:2:5: error: expected type 'void', found 'anyerror'",
|
||||
"tmp.zig:1:15: note: return type declared here",
|
||||
});
|
||||
|
||||
cases.add("invalid pointer for var type",
|
||||
@ -5734,7 +5742,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ @export(entry, .{.name = "entry", .linkage = @as(u32, 1234) });
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:3:50: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
|
||||
"tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'",
|
||||
});
|
||||
|
||||
cases.add("struct with invalid field",
|
||||
|
@ -51,11 +51,15 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in main (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in std.start.main (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -74,13 +78,21 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in foo (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in std.start.main (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in std.start.main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -99,17 +111,33 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in make_error (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in bar (test)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in foo (test)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in std.start.main (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in std.start.main (test)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in std.start.main (test)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in std.start.main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -130,11 +158,15 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in main (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -153,13 +185,21 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in foo (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -178,17 +218,33 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in make_error (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in bar (test)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in foo (test)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in main (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in std.start.posixCallMainAndExit (test)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -209,11 +265,15 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in _main.0 (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in _main (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -232,13 +292,21 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in _foo (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in _main.0 (test.o)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in _main (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in _main (test.o)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -257,17 +325,33 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in _make_error (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in _bar (test.o)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in _foo (test.o)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in _main.0 (test.o)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in _main (test.o)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in _main (test.o)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in _main (test.o)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in _main (test.o)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-fast
|
||||
@ -288,6 +372,8 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in main (test.obj)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
@ -309,7 +395,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:4:5: [address] in foo (test.obj)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in main (test.obj)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
@ -331,9 +421,17 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||
// debug
|
||||
\\error: TheSkyIsFalling
|
||||
\\source.zig:12:5: [address] in make_error (test.obj)
|
||||
\\ return error.TheSkyIsFalling;
|
||||
\\ ^
|
||||
\\source.zig:8:5: [address] in bar (test.obj)
|
||||
\\ return make_error();
|
||||
\\ ^
|
||||
\\source.zig:4:5: [address] in foo (test.obj)
|
||||
\\ try bar();
|
||||
\\ ^
|
||||
\\source.zig:16:5: [address] in main (test.obj)
|
||||
\\ try foo();
|
||||
\\ ^
|
||||
\\
|
||||
,
|
||||
// release-safe
|
||||
|
@ -1182,6 +1182,42 @@ test "suspend in for loop" {
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "suspend in while loop" {
|
||||
const S = struct {
|
||||
var global_frame: ?anyframe = null;
|
||||
|
||||
fn doTheTest() void {
|
||||
_ = async atest();
|
||||
while (global_frame) |f| resume f;
|
||||
}
|
||||
|
||||
fn atest() void {
|
||||
expect(optional(6) == 6);
|
||||
expect(errunion(6) == 6);
|
||||
}
|
||||
fn optional(stuff: ?u32) u32 {
|
||||
global_frame = @frame();
|
||||
defer global_frame = null;
|
||||
while (stuff) |val| {
|
||||
suspend;
|
||||
return val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fn errunion(stuff: anyerror!u32) u32 {
|
||||
global_frame = @frame();
|
||||
defer global_frame = null;
|
||||
while (stuff) |val| {
|
||||
suspend;
|
||||
return val;
|
||||
} else |err| {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "correctly spill when returning the error union result of another async fn" {
|
||||
const S = struct {
|
||||
var global_frame: anyframe = undefined;
|
||||
|
@ -167,3 +167,23 @@ test "nested bitcast" {
|
||||
S.foo(42);
|
||||
comptime S.foo(42);
|
||||
}
|
||||
|
||||
test "bitcast passed as tuple element" {
|
||||
const S = struct {
|
||||
fn foo(args: var) void {
|
||||
comptime expect(@TypeOf(args[0]) == f32);
|
||||
expect(args[0] == 12.34);
|
||||
}
|
||||
};
|
||||
S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))});
|
||||
}
|
||||
|
||||
test "triple level result location with bitcast sandwich passed as tuple element" {
|
||||
const S = struct {
|
||||
fn foo(args: var) void {
|
||||
comptime expect(@TypeOf(args[0]) == f64);
|
||||
expect(args[0] > 12.33 and args[0] < 12.35);
|
||||
}
|
||||
};
|
||||
S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))});
|
||||
}
|
||||
|
@ -804,3 +804,16 @@ test "comptime assign int to optional int" {
|
||||
expectEqual(20, x.?);
|
||||
}
|
||||
}
|
||||
|
||||
test "return 0 from function that has u0 return type" {
|
||||
const S = struct {
|
||||
fn foo_zero() u0 {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
comptime {
|
||||
if (S.foo_zero() != 0) {
|
||||
@compileError("test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ fn testSqrt() void {
|
||||
// expect(@sqrt(a) == 7);
|
||||
//}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||
var result = @sqrt(v);
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -86,7 +86,7 @@ fn testSin() void {
|
||||
expect(@sin(a) == 0);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||
var result = @sin(v);
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -116,7 +116,7 @@ fn testCos() void {
|
||||
expect(@cos(a) == 1);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||
var result = @cos(v);
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -146,7 +146,7 @@ fn testExp() void {
|
||||
expect(@exp(a) == 1);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||
var result = @exp(v);
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -176,7 +176,7 @@ fn testExp2() void {
|
||||
expect(@exp2(a) == 4);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||
var result = @exp2(v);
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -208,7 +208,7 @@ fn testLog() void {
|
||||
expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||
var result = @log(v);
|
||||
expect(math.approxEq(f32, @log(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -238,7 +238,7 @@ fn testLog2() void {
|
||||
expect(@log2(a) == 2);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||
var result = @log2(v);
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -268,7 +268,7 @@ fn testLog10() void {
|
||||
expect(@log10(a) == 3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||
var result = @log10(v);
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
|
||||
@ -304,7 +304,7 @@ fn testFabs() void {
|
||||
expect(@fabs(b) == 2.5);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||
var result = @fabs(v);
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
|
||||
@ -334,7 +334,7 @@ fn testFloor() void {
|
||||
expect(@floor(a) == 3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||
var result = @floor(v);
|
||||
expect(math.approxEq(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
|
||||
@ -364,7 +364,7 @@ fn testCeil() void {
|
||||
expect(@ceil(a) == 4);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||
var result = @ceil(v);
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
|
||||
@ -394,7 +394,7 @@ fn testTrunc() void {
|
||||
expect(@trunc(a) == -3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||
var result = @trunc(v);
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
|
||||
@ -403,6 +403,36 @@ fn testTrunc() void {
|
||||
}
|
||||
}
|
||||
|
||||
test "floating point comparisons" {
|
||||
testFloatComparisons();
|
||||
comptime testFloatComparisons();
|
||||
}
|
||||
|
||||
fn testFloatComparisons() void {
|
||||
inline for ([_]type{ f16, f32, f64, f128 }) |ty| {
|
||||
// No decimal part
|
||||
{
|
||||
const x: ty = 1.0;
|
||||
expect(x == 1);
|
||||
expect(x != 0);
|
||||
expect(x > 0);
|
||||
expect(x < 2);
|
||||
expect(x >= 1);
|
||||
expect(x <= 1);
|
||||
}
|
||||
// Non-zero decimal part
|
||||
{
|
||||
const x: ty = 1.5;
|
||||
expect(x != 1);
|
||||
expect(x != 2);
|
||||
expect(x > 1);
|
||||
expect(x < 2);
|
||||
expect(x >= 1);
|
||||
expect(x <= 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
|
||||
//test "@nearbyint" {
|
||||
// comptime testNearbyInt();
|
||||
|
@ -72,7 +72,7 @@ test "const result loc, runtime if cond, else unreachable" {
|
||||
|
||||
var t = true;
|
||||
const x = if (t) Num.Two else unreachable;
|
||||
if (x != .Two) @compileError("bad");
|
||||
expect(x == .Two);
|
||||
}
|
||||
|
||||
test "if prongs cast to expected type instead of peer type resolution" {
|
||||
|
@ -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);
|
||||
|
@ -781,3 +781,16 @@ test "pointer to thread local array" {
|
||||
std.mem.copy(u8, buffer[0..], s);
|
||||
std.testing.expectEqualSlices(u8, buffer[0..], s);
|
||||
}
|
||||
|
||||
test "auto created variables have correct alignment" {
|
||||
const S = struct {
|
||||
fn foo(str: [*]const u8) u32 {
|
||||
for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| {
|
||||
return v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
|
||||
comptime expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
|
||||
}
|
||||
|
@ -153,3 +153,25 @@ test "optional with void type" {
|
||||
var x = Foo{ .x = null };
|
||||
expect(x.x == null);
|
||||
}
|
||||
|
||||
test "0-bit child type coerced to optional return ptr result location" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
var y = Foo{};
|
||||
var z = y.thing();
|
||||
expect(z != null);
|
||||
}
|
||||
|
||||
const Foo = struct {
|
||||
pub const Bar = struct {
|
||||
field: *Foo,
|
||||
};
|
||||
|
||||
pub fn thing(self: *Foo) ?Bar {
|
||||
return Bar{ .field = self };
|
||||
}
|
||||
};
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
@ -479,3 +479,17 @@ test "switch on pointer type" {
|
||||
comptime expect(2 == S.doTheTest(S.P2));
|
||||
comptime expect(3 == S.doTheTest(S.P3));
|
||||
}
|
||||
|
||||
test "switch on error set with single else" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
var some: error{Foo} = error.Foo;
|
||||
expect(switch (some) {
|
||||
else => |a| true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
const expect = @import("std").testing.expect;
|
||||
const mem = @import("std").mem;
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const mem = std.mem;
|
||||
|
||||
fn initStaticArray() [10]i32 {
|
||||
var array: [10]i32 = undefined;
|
||||
|
405
test/tests.zig
405
test/tests.zig
@ -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
|
||||
@ -598,6 +622,9 @@ pub const StackTracesContext = struct {
|
||||
child.stderr_behavior = .Pipe;
|
||||
child.env_map = b.env_map;
|
||||
|
||||
if (b.verbose) {
|
||||
printInvocation(args.toSliceConst());
|
||||
}
|
||||
child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) });
|
||||
|
||||
var stdout = Buffer.initNull(b.allocator);
|
||||
|
@ -1,7 +1,43 @@
|
||||
const tests = @import("tests.zig");
|
||||
const builtin = @import("builtin");
|
||||
const Target = @import("std").Target;
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("function prototype with parenthesis",
|
||||
\\void (f0) (void *L);
|
||||
\\void ((f1)) (void *L);
|
||||
\\void (((f2))) (void *L);
|
||||
, &[_][]const u8{
|
||||
\\pub extern fn f0(L: ?*c_void) void;
|
||||
\\pub extern fn f1(L: ?*c_void) void;
|
||||
\\pub extern fn f2(L: ?*c_void) void;
|
||||
});
|
||||
|
||||
cases.add("array initializer w/ typedef",
|
||||
\\typedef unsigned char uuid_t[16];
|
||||
\\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
, &[_][]const u8{
|
||||
\\pub const uuid_t = [16]u8;
|
||||
\\pub const UUID_NULL: uuid_t = .{
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\};
|
||||
});
|
||||
|
||||
cases.add("empty declaration",
|
||||
\\;
|
||||
, &[_][]const u8{""});
|
||||
@ -1005,7 +1041,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);
|
||||
@ -1021,7 +1062,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);
|
||||
@ -1031,7 +1077,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{
|
||||
@ -2590,4 +2641,15 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return foo((@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(c)))) != @intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(b))))));
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("Don't make const parameters mutable",
|
||||
\\int max(const int x, int y) {
|
||||
\\ return (x > y) ? x : y;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(x: c_int, arg_y: c_int) c_int {
|
||||
\\ var y = arg_y;
|
||||
\\ return if (x > y) x else y;
|
||||
\\}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user