mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
Merge remote-tracking branch 'origin/master' into llvm13
This commit is contained in:
commit
7efca2e6f5
@ -9,7 +9,7 @@ sudo apt-get install -y cmake s3cmd tidy
|
||||
ZIGDIR="$(pwd)"
|
||||
ARCH="$(uname -m)"
|
||||
TARGET="$ARCH-linux-musl"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.0-dev.2703+c12704a33"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.1-dev.94+535615117"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
MCPU="baseline"
|
||||
JOBS="-j$(nproc)"
|
||||
|
||||
@ -9,7 +9,7 @@ ZIGDIR="$(pwd)"
|
||||
ARCH="x86_64"
|
||||
TARGET="$ARCH-macos-gnu"
|
||||
MCPU="baseline"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.0-dev.2703+c12704a33"
|
||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.8.1-dev.94+535615117"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
JOBS="-j2"
|
||||
|
||||
|
||||
@ -783,7 +783,7 @@ pub fn main() void {
|
||||
Because Zig source code is {#link|UTF-8 encoded|Source Encoding#}, any non-ASCII bytes appearing within a string literal
|
||||
in source code carry their UTF-8 meaning into the content of the string in the Zig program;
|
||||
the bytes are not modified by the compiler.
|
||||
However, it is possible to embbed non-UTF-8 bytes into a string literal using <code>\xNN</code> notation.
|
||||
However, it is possible to embed non-UTF-8 bytes into a string literal using <code>\xNN</code> notation.
|
||||
</p>
|
||||
<p>
|
||||
Unicode code point literals have type {#syntax#}comptime_int{#endsyntax#}, the same as
|
||||
|
||||
@ -700,7 +700,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ int $128
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.x86_64 => asm volatile (
|
||||
@ -713,7 +713,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ syscall
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.arm, .armeb, .thumb, .thumbeb => asm volatile (
|
||||
@ -726,7 +726,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ svc 0
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.aarch64, .aarch64_be, .aarch64_32 => asm volatile (
|
||||
@ -739,7 +739,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ svc 0
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.mips, .mipsel => asm volatile (
|
||||
@ -753,7 +753,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ syscall
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.mips64, .mips64el => asm volatile (
|
||||
@ -766,7 +766,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ syscall
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile (
|
||||
@ -780,7 +780,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ blr
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.riscv64 => asm volatile (
|
||||
@ -793,7 +793,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ ecall
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
.sparcv9 => asm volatile (
|
||||
@ -821,7 +821,7 @@ const LinuxThreadImpl = struct {
|
||||
\\ t 0x6d
|
||||
:
|
||||
: [ptr] "r" (@ptrToInt(self.mapped.ptr)),
|
||||
[len] "r" (self.mapped.len)
|
||||
[len] "r" (self.mapped.len),
|
||||
: "memory"
|
||||
),
|
||||
else => |cpu_arch| @compileError("Unsupported linux arch: " ++ @tagName(cpu_arch)),
|
||||
|
||||
@ -293,6 +293,22 @@ pub fn ArrayHashMap(
|
||||
return self.unmanaged.getPtrAdapted(key, ctx);
|
||||
}
|
||||
|
||||
/// Find the actual key associated with an adapted key
|
||||
pub fn getKey(self: Self, key: K) ?K {
|
||||
return self.unmanaged.getKeyContext(key, self.ctx);
|
||||
}
|
||||
pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
|
||||
return self.unmanaged.getKeyAdapted(key, ctx);
|
||||
}
|
||||
|
||||
/// Find a pointer to the actual key associated with an adapted key
|
||||
pub fn getKeyPtr(self: Self, key: K) ?*K {
|
||||
return self.unmanaged.getKeyPtrContext(key, self.ctx);
|
||||
}
|
||||
pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
|
||||
return self.unmanaged.getKeyPtrAdapted(key, ctx);
|
||||
}
|
||||
|
||||
/// Check whether a key is stored in the map
|
||||
pub fn contains(self: Self, key: K) bool {
|
||||
return self.unmanaged.containsContext(key, self.ctx);
|
||||
@ -967,6 +983,34 @@ pub fn ArrayHashMapUnmanaged(
|
||||
return if (@sizeOf(*V) == 0) @as(*V, undefined) else &self.values()[index];
|
||||
}
|
||||
|
||||
/// Find the actual key associated with an adapted key
|
||||
pub fn getKey(self: Self, key: K) ?K {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead.");
|
||||
return self.getKeyContext(key, undefined);
|
||||
}
|
||||
pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K {
|
||||
return self.getKeyAdapted(key, ctx);
|
||||
}
|
||||
pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
|
||||
const index = self.getIndexAdapted(key, ctx) orelse return null;
|
||||
return self.keys()[index];
|
||||
}
|
||||
|
||||
/// Find a pointer to the actual key associated with an adapted key
|
||||
pub fn getKeyPtr(self: Self, key: K) ?*K {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead.");
|
||||
return self.getKeyPtrContext(key, undefined);
|
||||
}
|
||||
pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K {
|
||||
return self.getKeyPtrAdapted(key, ctx);
|
||||
}
|
||||
pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
|
||||
const index = self.getIndexAdapted(key, ctx) orelse return null;
|
||||
return &self.keys()[index];
|
||||
}
|
||||
|
||||
/// Check whether a key is stored in the map
|
||||
pub fn contains(self: Self, key: K) bool {
|
||||
if (@sizeOf(Context) != 0)
|
||||
|
||||
@ -176,69 +176,69 @@ pub fn Atomic(comptime T: type) type {
|
||||
2 => switch (op) {
|
||||
.Set => asm volatile ("lock btsw %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Reset => asm volatile ("lock btrw %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Toggle => asm volatile ("lock btcw %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
},
|
||||
4 => switch (op) {
|
||||
.Set => asm volatile ("lock btsl %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Reset => asm volatile ("lock btrl %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Toggle => asm volatile ("lock btcl %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
},
|
||||
8 => switch (op) {
|
||||
.Set => asm volatile ("lock btsq %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Reset => asm volatile ("lock btrq %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
.Toggle => asm volatile ("lock btcq %[bit], %[ptr]"
|
||||
// LLVM doesn't support u1 flag register return values
|
||||
: [result] "={@ccc}" (-> u8)
|
||||
: [result] "={@ccc}" (-> u8),
|
||||
: [ptr] "*p" (&self.value),
|
||||
[bit] "X" (@as(T, bit))
|
||||
[bit] "X" (@as(T, bit)),
|
||||
: "cc", "memory"
|
||||
),
|
||||
},
|
||||
|
||||
@ -94,6 +94,8 @@ pub const Builder = struct {
|
||||
name: []const u8,
|
||||
type_id: TypeId,
|
||||
description: []const u8,
|
||||
/// If the `type_id` is `enum` this provides the list of enum options
|
||||
enum_options: ?[]const []const u8,
|
||||
};
|
||||
|
||||
const UserInputOption = struct {
|
||||
@ -482,10 +484,21 @@ pub const Builder = struct {
|
||||
const name = self.dupe(name_raw);
|
||||
const description = self.dupe(description_raw);
|
||||
const type_id = comptime typeToEnum(T);
|
||||
const enum_options = if (type_id == .@"enum") blk: {
|
||||
const fields = comptime std.meta.fields(T);
|
||||
var options = ArrayList([]const u8).initCapacity(self.allocator, fields.len) catch unreachable;
|
||||
|
||||
inline for (fields) |field| {
|
||||
options.appendAssumeCapacity(field.name);
|
||||
}
|
||||
|
||||
break :blk options.toOwnedSlice();
|
||||
} else null;
|
||||
const available_option = AvailableOption{
|
||||
.name = name,
|
||||
.type_id = type_id,
|
||||
.description = description,
|
||||
.enum_options = enum_options,
|
||||
};
|
||||
if ((self.available_options_map.fetchPut(name, available_option) catch unreachable) != null) {
|
||||
panic("Option '{s}' declared twice", .{name});
|
||||
|
||||
@ -34,9 +34,9 @@ pub const Block = struct {
|
||||
return Block{
|
||||
.repr = asm (
|
||||
\\ vaesenc %[rk], %[in], %[out]
|
||||
: [out] "=x" (-> BlockVec)
|
||||
: [out] "=x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (round_key.repr)
|
||||
[rk] "x" (round_key.repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -46,9 +46,9 @@ pub const Block = struct {
|
||||
return Block{
|
||||
.repr = asm (
|
||||
\\ vaesenclast %[rk], %[in], %[out]
|
||||
: [out] "=x" (-> BlockVec)
|
||||
: [out] "=x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (round_key.repr)
|
||||
[rk] "x" (round_key.repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -58,9 +58,9 @@ pub const Block = struct {
|
||||
return Block{
|
||||
.repr = asm (
|
||||
\\ vaesdec %[rk], %[in], %[out]
|
||||
: [out] "=x" (-> BlockVec)
|
||||
: [out] "=x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (inv_round_key.repr)
|
||||
[rk] "x" (inv_round_key.repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -70,9 +70,9 @@ pub const Block = struct {
|
||||
return Block{
|
||||
.repr = asm (
|
||||
\\ vaesdeclast %[rk], %[in], %[out]
|
||||
: [out] "=x" (-> BlockVec)
|
||||
: [out] "=x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (inv_round_key.repr)
|
||||
[rk] "x" (inv_round_key.repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -190,11 +190,11 @@ fn KeySchedule(comptime Aes: type) type {
|
||||
\\ vpxor %[ts], %[r], %[r]
|
||||
: [r] "=&x" (-> BlockVec),
|
||||
[s] "=&x" (s),
|
||||
[ts] "=&x" (ts)
|
||||
[ts] "=&x" (ts),
|
||||
: [rc] "n" (rc),
|
||||
[t] "x" (t),
|
||||
[tx] "x" (tx),
|
||||
[mask] "n" (@as(u8, if (second) 0xaa else 0xff))
|
||||
[mask] "n" (@as(u8, if (second) 0xaa else 0xff)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -235,8 +235,8 @@ fn KeySchedule(comptime Aes: type) type {
|
||||
inv_round_keys[i] = Block{
|
||||
.repr = asm (
|
||||
\\ vaesimc %[rk], %[inv_rk]
|
||||
: [inv_rk] "=x" (-> BlockVec)
|
||||
: [rk] "x" (round_keys[rounds - i].repr)
|
||||
: [inv_rk] "=x" (-> BlockVec),
|
||||
: [rk] "x" (round_keys[rounds - i].repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@ -39,10 +39,10 @@ pub const Block = struct {
|
||||
\\ aese %[out].16b, %[zero].16b
|
||||
\\ aesmc %[out].16b, %[out].16b
|
||||
\\ eor %[out].16b, %[out].16b, %[rk].16b
|
||||
: [out] "=&x" (-> BlockVec)
|
||||
: [out] "=&x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (round_key.repr),
|
||||
[zero] "x" (zero)
|
||||
[zero] "x" (zero),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -54,10 +54,10 @@ pub const Block = struct {
|
||||
\\ mov %[out].16b, %[in].16b
|
||||
\\ aese %[out].16b, %[zero].16b
|
||||
\\ eor %[out].16b, %[out].16b, %[rk].16b
|
||||
: [out] "=&x" (-> BlockVec)
|
||||
: [out] "=&x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (round_key.repr),
|
||||
[zero] "x" (zero)
|
||||
[zero] "x" (zero),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -70,10 +70,10 @@ pub const Block = struct {
|
||||
\\ aesd %[out].16b, %[zero].16b
|
||||
\\ aesimc %[out].16b, %[out].16b
|
||||
\\ eor %[out].16b, %[out].16b, %[rk].16b
|
||||
: [out] "=&x" (-> BlockVec)
|
||||
: [out] "=&x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (inv_round_key.repr),
|
||||
[zero] "x" (zero)
|
||||
[zero] "x" (zero),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -85,10 +85,10 @@ pub const Block = struct {
|
||||
\\ mov %[out].16b, %[in].16b
|
||||
\\ aesd %[out].16b, %[zero].16b
|
||||
\\ eor %[out].16b, %[out].16b, %[rk].16b
|
||||
: [out] "=&x" (-> BlockVec)
|
||||
: [out] "=&x" (-> BlockVec),
|
||||
: [in] "x" (block.repr),
|
||||
[rk] "x" (inv_round_key.repr),
|
||||
[zero] "x" (zero)
|
||||
[zero] "x" (zero),
|
||||
),
|
||||
};
|
||||
}
|
||||
@ -210,11 +210,11 @@ fn KeySchedule(comptime Aes: type) type {
|
||||
[v1] "=&x" (v1),
|
||||
[v2] "=&x" (v2),
|
||||
[v3] "=&x" (v3),
|
||||
[v4] "=&x" (v4)
|
||||
[v4] "=&x" (v4),
|
||||
: [rc] "N" (rc),
|
||||
[t] "x" (t),
|
||||
[zero] "x" (zero),
|
||||
[mask] "x" (mask1)
|
||||
[mask] "x" (mask1),
|
||||
);
|
||||
}
|
||||
|
||||
@ -240,12 +240,12 @@ fn KeySchedule(comptime Aes: type) type {
|
||||
[v1] "=&x" (v1),
|
||||
[v2] "=&x" (v2),
|
||||
[v3] "=&x" (v3),
|
||||
[v4] "=&x" (v4)
|
||||
[v4] "=&x" (v4),
|
||||
: [rc] "N" (if (second) @as(u8, 0) else rc),
|
||||
[t] "x" (t),
|
||||
[tx] "x" (tx),
|
||||
[zero] "x" (zero),
|
||||
[mask] "x" (if (second) mask2 else mask1)
|
||||
[mask] "x" (if (second) mask2 else mask1),
|
||||
);
|
||||
}
|
||||
|
||||
@ -286,8 +286,8 @@ fn KeySchedule(comptime Aes: type) type {
|
||||
inv_round_keys[i] = Block{
|
||||
.repr = asm (
|
||||
\\ aesimc %[inv_rk].16b, %[rk].16b
|
||||
: [inv_rk] "=x" (-> BlockVec)
|
||||
: [rk] "x" (round_keys[rounds - i].repr)
|
||||
: [inv_rk] "=x" (-> BlockVec),
|
||||
: [rk] "x" (round_keys[rounds - i].repr),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@ -94,9 +94,9 @@ pub const Ghash = struct {
|
||||
const Vector = std.meta.Vector;
|
||||
const product = asm (
|
||||
\\ vpclmulqdq $0x00, %[x], %[y], %[out]
|
||||
: [out] "=x" (-> Vector(2, u64))
|
||||
: [out] "=x" (-> Vector(2, u64)),
|
||||
: [x] "x" (@bitCast(Vector(2, u64), @as(u128, x))),
|
||||
[y] "x" (@bitCast(Vector(2, u64), @as(u128, y)))
|
||||
[y] "x" (@bitCast(Vector(2, u64), @as(u128, y))),
|
||||
);
|
||||
return product[0];
|
||||
}
|
||||
@ -105,9 +105,9 @@ pub const Ghash = struct {
|
||||
const Vector = std.meta.Vector;
|
||||
const product = asm (
|
||||
\\ pmull %[out].1q, %[x].1d, %[y].1d
|
||||
: [out] "=w" (-> Vector(2, u64))
|
||||
: [out] "=w" (-> Vector(2, u64)),
|
||||
: [x] "w" (@bitCast(Vector(2, u64), @as(u128, x))),
|
||||
[y] "w" (@bitCast(Vector(2, u64), @as(u128, y)))
|
||||
[y] "w" (@bitCast(Vector(2, u64), @as(u128, y))),
|
||||
);
|
||||
return product[0];
|
||||
}
|
||||
|
||||
@ -1634,7 +1634,7 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u
|
||||
|
||||
pub fn dumpStackPointerAddr(prefix: []const u8) void {
|
||||
const sp = asm (""
|
||||
: [argc] "={rsp}" (-> usize)
|
||||
: [argc] "={rsp}" (-> usize),
|
||||
);
|
||||
std.debug.warn("{} sp = 0x{x}\n", .{ prefix, sp });
|
||||
}
|
||||
|
||||
@ -1200,8 +1200,6 @@ pub fn formatFloatDecimal(
|
||||
while (i < precision) : (i += 1) {
|
||||
try writer.writeAll("0");
|
||||
}
|
||||
} else {
|
||||
try writer.writeAll(".0");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2198,6 +2196,7 @@ test "float.hexadecimal.precision" {
|
||||
test "float.decimal" {
|
||||
try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
|
||||
try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
|
||||
try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)});
|
||||
try expectFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
|
||||
try expectFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
|
||||
// -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
|
||||
|
||||
@ -561,6 +561,21 @@ pub fn HashMap(
|
||||
return self.unmanaged.getPtrAdapted(key, ctx);
|
||||
}
|
||||
|
||||
/// Finds the actual key associated with an adapted key in the map
|
||||
pub fn getKey(self: Self, key: K) ?K {
|
||||
return self.unmanaged.getKeyContext(key, self.ctx);
|
||||
}
|
||||
pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
|
||||
return self.unmanaged.getKeyAdapted(key, ctx);
|
||||
}
|
||||
|
||||
pub fn getKeyPtr(self: Self, key: K) ?*K {
|
||||
return self.unmanaged.getKeyPtrContext(key, self.ctx);
|
||||
}
|
||||
pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
|
||||
return self.unmanaged.getKeyPtrAdapted(key, ctx);
|
||||
}
|
||||
|
||||
/// Finds the key and value associated with a key in the map
|
||||
pub fn getEntry(self: Self, key: K) ?Entry {
|
||||
return self.unmanaged.getEntryContext(key, self.ctx);
|
||||
@ -1124,6 +1139,38 @@ pub fn HashMapUnmanaged(
|
||||
result.value_ptr.* = value;
|
||||
}
|
||||
|
||||
/// Get an optional pointer to the actual key associated with adapted key, if present.
|
||||
pub fn getKeyPtr(self: Self, key: K) ?*K {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead.");
|
||||
return self.getKeyPtrContext(key, undefined);
|
||||
}
|
||||
pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K {
|
||||
return self.getKeyPtrAdapted(key, ctx);
|
||||
}
|
||||
pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
|
||||
if (self.getIndex(key, ctx)) |idx| {
|
||||
return &self.keys()[idx];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get a copy of the actual key associated with adapted key, if present.
|
||||
pub fn getKey(self: Self, key: K) ?K {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead.");
|
||||
return self.getKeyContext(key, undefined);
|
||||
}
|
||||
pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K {
|
||||
return self.getKeyAdapted(key, ctx);
|
||||
}
|
||||
pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
|
||||
if (self.getIndex(key, ctx)) |idx| {
|
||||
return self.keys()[idx];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get an optional pointer to the value associated with key, if present.
|
||||
pub fn getPtr(self: Self, key: K) ?*V {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@ -1948,6 +1995,7 @@ test "std.hash_map getOrPutAdapted" {
|
||||
try testing.expect(result.found_existing);
|
||||
try testing.expectEqual(real_keys[i], result.key_ptr.*);
|
||||
try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*);
|
||||
try testing.expectEqual(real_keys[i], map.getKeyAdapted(key_str, AdaptedContext{}).?);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2860,7 +2860,7 @@ pub fn alignForwardGeneric(comptime T: type, addr: T, alignment: T) T {
|
||||
pub fn doNotOptimizeAway(val: anytype) void {
|
||||
asm volatile (""
|
||||
:
|
||||
: [val] "rm" (val)
|
||||
: [val] "rm" (val),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,63 +2,63 @@ usingnamespace @import("../bits/linux.zig");
|
||||
|
||||
pub fn syscall0(number: SYS) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [number] "{r7}" (@enumToInt(number))
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1)
|
||||
[arg1] "{r0}" (arg1),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2)
|
||||
[arg2] "{r1}" (arg2),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3)
|
||||
[arg3] "{r2}" (arg3),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4)
|
||||
[arg4] "{r3}" (arg4),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4),
|
||||
[arg5] "{r4}" (arg5)
|
||||
[arg5] "{r4}" (arg5),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -73,14 +73,14 @@ pub fn syscall6(
|
||||
arg6: usize,
|
||||
) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [number] "{r7}" (@enumToInt(number)),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4),
|
||||
[arg5] "{r4}" (arg5),
|
||||
[arg6] "{r5}" (arg6)
|
||||
[arg6] "{r5}" (arg6),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -91,7 +91,7 @@ pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags:
|
||||
pub fn restore() callconv(.Naked) void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (@enumToInt(SYS.sigreturn))
|
||||
: [number] "{r7}" (@enumToInt(SYS.sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -99,7 +99,7 @@ pub fn restore() callconv(.Naked) void {
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{r7}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,63 +2,63 @@ usingnamespace @import("../bits/linux.zig");
|
||||
|
||||
pub fn syscall0(number: SYS) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [number] "{x8}" (@enumToInt(number))
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1)
|
||||
[arg1] "{x0}" (arg1),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1),
|
||||
[arg2] "{x1}" (arg2)
|
||||
[arg2] "{x1}" (arg2),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1),
|
||||
[arg2] "{x1}" (arg2),
|
||||
[arg3] "{x2}" (arg3)
|
||||
[arg3] "{x2}" (arg3),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1),
|
||||
[arg2] "{x1}" (arg2),
|
||||
[arg3] "{x2}" (arg3),
|
||||
[arg4] "{x3}" (arg4)
|
||||
[arg4] "{x3}" (arg4),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1),
|
||||
[arg2] "{x1}" (arg2),
|
||||
[arg3] "{x2}" (arg3),
|
||||
[arg4] "{x3}" (arg4),
|
||||
[arg5] "{x4}" (arg5)
|
||||
[arg5] "{x4}" (arg5),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
@ -73,14 +73,14 @@ pub fn syscall6(
|
||||
arg6: usize,
|
||||
) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
: [ret] "={x0}" (-> usize),
|
||||
: [number] "{x8}" (@enumToInt(number)),
|
||||
[arg1] "{x0}" (arg1),
|
||||
[arg2] "{x1}" (arg2),
|
||||
[arg3] "{x2}" (arg3),
|
||||
[arg4] "{x3}" (arg4),
|
||||
[arg5] "{x4}" (arg5),
|
||||
[arg6] "{x5}" (arg6)
|
||||
[arg6] "{x5}" (arg6),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
@ -93,7 +93,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{x8}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,63 +2,63 @@ usingnamespace @import("../bits/linux.zig");
|
||||
|
||||
pub fn syscall0(number: SYS) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [number] "{eax}" (@enumToInt(number))
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1)
|
||||
[arg1] "{ebx}" (arg1),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2)
|
||||
[arg2] "{ecx}" (arg2),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2),
|
||||
[arg3] "{edx}" (arg3)
|
||||
[arg3] "{edx}" (arg3),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2),
|
||||
[arg3] "{edx}" (arg3),
|
||||
[arg4] "{esi}" (arg4)
|
||||
[arg4] "{esi}" (arg4),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2),
|
||||
[arg3] "{edx}" (arg3),
|
||||
[arg4] "{esi}" (arg4),
|
||||
[arg5] "{edi}" (arg5)
|
||||
[arg5] "{edi}" (arg5),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -83,24 +83,24 @@ pub fn syscall6(
|
||||
\\ int $0x80
|
||||
\\ pop %%ebp
|
||||
\\ add $4, %%esp
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2),
|
||||
[arg3] "{edx}" (arg3),
|
||||
[arg4] "{esi}" (arg4),
|
||||
[arg5] "{edi}" (arg5),
|
||||
[arg6] "rm" (arg6)
|
||||
[arg6] "rm" (arg6),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn socketcall(call: usize, args: [*]usize) usize {
|
||||
return asm volatile ("int $0x80"
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@enumToInt(SYS.socketcall)),
|
||||
[arg1] "{ebx}" (call),
|
||||
[arg2] "{ecx}" (@ptrToInt(args))
|
||||
[arg2] "{ecx}" (@ptrToInt(args)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -111,7 +111,7 @@ pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags:
|
||||
pub fn restore() callconv(.Naked) void {
|
||||
return asm volatile ("int $0x80"
|
||||
:
|
||||
: [number] "{eax}" (@enumToInt(SYS.sigreturn))
|
||||
: [number] "{eax}" (@enumToInt(SYS.sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -119,7 +119,7 @@ pub fn restore() callconv(.Naked) void {
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("int $0x80"
|
||||
:
|
||||
: [number] "{eax}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ pub fn syscall0(number: SYS) usize {
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [number] "{$2}" (@enumToInt(number))
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -25,9 +25,9 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
|
||||
\\ sw $2, 0($4)
|
||||
\\ sw $3, 4($4)
|
||||
\\ 2:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(SYS.pipe)),
|
||||
[fd] "{$4}" (fd)
|
||||
[fd] "{$4}" (fd),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -38,9 +38,9 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1)
|
||||
[arg1] "{$4}" (arg1),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -51,10 +51,10 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2)
|
||||
[arg2] "{$5}" (arg2),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -65,11 +65,11 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2),
|
||||
[arg3] "{$6}" (arg3)
|
||||
[arg3] "{$6}" (arg3),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -80,12 +80,12 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2),
|
||||
[arg3] "{$6}" (arg3),
|
||||
[arg4] "{$7}" (arg4)
|
||||
[arg4] "{$7}" (arg4),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -100,13 +100,13 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2),
|
||||
[arg3] "{$6}" (arg3),
|
||||
[arg4] "{$7}" (arg4),
|
||||
[arg5] "r" (arg5)
|
||||
[arg5] "r" (arg5),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -133,14 +133,14 @@ pub fn syscall6(
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2),
|
||||
[arg3] "{$6}" (arg3),
|
||||
[arg4] "{$7}" (arg4),
|
||||
[arg5] "r" (arg5),
|
||||
[arg6] "r" (arg6)
|
||||
[arg6] "r" (arg6),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -166,7 +166,7 @@ pub fn syscall7(
|
||||
\\ blez $7, 1f
|
||||
\\ subu $2, $0, $2
|
||||
\\ 1:
|
||||
: [ret] "={$2}" (-> usize)
|
||||
: [ret] "={$2}" (-> usize),
|
||||
: [number] "{$2}" (@enumToInt(number)),
|
||||
[arg1] "{$4}" (arg1),
|
||||
[arg2] "{$5}" (arg2),
|
||||
@ -174,7 +174,7 @@ pub fn syscall7(
|
||||
[arg4] "{$7}" (arg4),
|
||||
[arg5] "r" (arg5),
|
||||
[arg6] "r" (arg6),
|
||||
[arg7] "r" (arg7)
|
||||
[arg7] "r" (arg7),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -185,7 +185,7 @@ pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags:
|
||||
pub fn restore() callconv(.Naked) void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{$2}" (@enumToInt(SYS.sigreturn))
|
||||
: [number] "{$2}" (@enumToInt(SYS.sigreturn)),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
@ -193,7 +193,7 @@ pub fn restore() callconv(.Naked) void {
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{$2}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{$2}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ pub fn syscall0(number: SYS) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [number] "{r0}" (@enumToInt(number))
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -18,9 +18,9 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1)
|
||||
[arg1] "{r3}" (arg1),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -31,10 +31,10 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2)
|
||||
[arg2] "{r4}" (arg2),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -45,11 +45,11 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3)
|
||||
[arg3] "{r5}" (arg3),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -60,12 +60,12 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4)
|
||||
[arg4] "{r6}" (arg4),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -76,13 +76,13 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4),
|
||||
[arg5] "{r7}" (arg5)
|
||||
[arg5] "{r7}" (arg5),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -101,14 +101,14 @@ pub fn syscall6(
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4),
|
||||
[arg5] "{r7}" (arg5),
|
||||
[arg6] "{r8}" (arg6)
|
||||
[arg6] "{r8}" (arg6),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -121,7 +121,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("sc"
|
||||
:
|
||||
: [number] "{r0}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{r0}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ pub fn syscall0(number: SYS) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [number] "{r0}" (@enumToInt(number))
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -18,9 +18,9 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1)
|
||||
[arg1] "{r3}" (arg1),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -31,10 +31,10 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2)
|
||||
[arg2] "{r4}" (arg2),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -45,11 +45,11 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3)
|
||||
[arg3] "{r5}" (arg3),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -60,12 +60,12 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4)
|
||||
[arg4] "{r6}" (arg4),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -76,13 +76,13 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4),
|
||||
[arg5] "{r7}" (arg5)
|
||||
[arg5] "{r7}" (arg5),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -101,14 +101,14 @@ pub fn syscall6(
|
||||
\\ bns+ 1f
|
||||
\\ neg 3, 3
|
||||
\\ 1:
|
||||
: [ret] "={r3}" (-> usize)
|
||||
: [ret] "={r3}" (-> usize),
|
||||
: [number] "{r0}" (@enumToInt(number)),
|
||||
[arg1] "{r3}" (arg1),
|
||||
[arg2] "{r4}" (arg2),
|
||||
[arg3] "{r5}" (arg3),
|
||||
[arg4] "{r6}" (arg4),
|
||||
[arg5] "{r7}" (arg5),
|
||||
[arg6] "{r8}" (arg6)
|
||||
[arg6] "{r8}" (arg6),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
@ -121,7 +121,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("sc"
|
||||
:
|
||||
: [number] "{r0}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{r0}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,63 +2,63 @@ usingnamespace @import("../bits/linux.zig");
|
||||
|
||||
pub fn syscall0(number: SYS) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [number] "{x17}" (@enumToInt(number))
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1)
|
||||
[arg1] "{x10}" (arg1),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1),
|
||||
[arg2] "{x11}" (arg2)
|
||||
[arg2] "{x11}" (arg2),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1),
|
||||
[arg2] "{x11}" (arg2),
|
||||
[arg3] "{x12}" (arg3)
|
||||
[arg3] "{x12}" (arg3),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1),
|
||||
[arg2] "{x11}" (arg2),
|
||||
[arg3] "{x12}" (arg3),
|
||||
[arg4] "{x13}" (arg4)
|
||||
[arg4] "{x13}" (arg4),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1),
|
||||
[arg2] "{x11}" (arg2),
|
||||
[arg3] "{x12}" (arg3),
|
||||
[arg4] "{x13}" (arg4),
|
||||
[arg5] "{x14}" (arg5)
|
||||
[arg5] "{x14}" (arg5),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -73,14 +73,14 @@ pub fn syscall6(
|
||||
arg6: usize,
|
||||
) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
: [ret] "={x10}" (-> usize),
|
||||
: [number] "{x17}" (@enumToInt(number)),
|
||||
[arg1] "{x10}" (arg1),
|
||||
[arg2] "{x11}" (arg2),
|
||||
[arg3] "{x12}" (arg3),
|
||||
[arg4] "{x13}" (arg4),
|
||||
[arg5] "{x14}" (arg5),
|
||||
[arg6] "{x15}" (arg6)
|
||||
[arg6] "{x15}" (arg6),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -92,7 +92,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("ecall"
|
||||
:
|
||||
: [number] "{x17}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{x17}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -14,9 +14,9 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
|
||||
\\ st %%o1, [%%g3+4]
|
||||
\\ clr %%o0
|
||||
\\2:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(SYS.pipe)),
|
||||
[arg] "r" (fd)
|
||||
[arg] "r" (fd),
|
||||
: "memory", "g3"
|
||||
);
|
||||
}
|
||||
@ -38,8 +38,8 @@ pub fn syscall_fork() usize {
|
||||
\\ dec %%o1
|
||||
\\ and %%o1, %%o0, %%o0
|
||||
\\ 2:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [number] "{g1}" (@enumToInt(SYS.fork))
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(SYS.fork)),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -51,8 +51,8 @@ pub fn syscall0(number: SYS) usize {
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [number] "{g1}" (@enumToInt(number))
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -64,9 +64,9 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1)
|
||||
[arg1] "{o0}" (arg1),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -78,10 +78,10 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1),
|
||||
[arg2] "{o1}" (arg2)
|
||||
[arg2] "{o1}" (arg2),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -93,11 +93,11 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1),
|
||||
[arg2] "{o1}" (arg2),
|
||||
[arg3] "{o2}" (arg3)
|
||||
[arg3] "{o2}" (arg3),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -109,12 +109,12 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1),
|
||||
[arg2] "{o1}" (arg2),
|
||||
[arg3] "{o2}" (arg3),
|
||||
[arg4] "{o3}" (arg4)
|
||||
[arg4] "{o3}" (arg4),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -126,13 +126,13 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1),
|
||||
[arg2] "{o1}" (arg2),
|
||||
[arg3] "{o2}" (arg3),
|
||||
[arg4] "{o3}" (arg4),
|
||||
[arg5] "{o4}" (arg5)
|
||||
[arg5] "{o4}" (arg5),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -152,14 +152,14 @@ pub fn syscall6(
|
||||
\\ nop
|
||||
\\ neg %%o0
|
||||
\\ 1:
|
||||
: [ret] "={o0}" (-> usize)
|
||||
: [ret] "={o0}" (-> usize),
|
||||
: [number] "{g1}" (@enumToInt(number)),
|
||||
[arg1] "{o0}" (arg1),
|
||||
[arg2] "{o1}" (arg2),
|
||||
[arg3] "{o2}" (arg3),
|
||||
[arg4] "{o3}" (arg4),
|
||||
[arg5] "{o4}" (arg5),
|
||||
[arg6] "{o5}" (arg6)
|
||||
[arg6] "{o5}" (arg6),
|
||||
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
@ -174,7 +174,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.C) void {
|
||||
return asm volatile ("t 0x6d"
|
||||
:
|
||||
: [number] "{g1}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{g1}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory", "xcc", "o0", "o1", "o2", "o3", "o4", "o5", "o7"
|
||||
);
|
||||
}
|
||||
|
||||
@ -30,13 +30,13 @@ fn getDynamicSymbol() [*]elf.Dyn {
|
||||
\\ call 1f
|
||||
\\ 1: pop %[ret]
|
||||
\\ lea _DYNAMIC-1b(%[ret]), %[ret]
|
||||
: [ret] "=r" (-> [*]elf.Dyn)
|
||||
: [ret] "=r" (-> [*]elf.Dyn),
|
||||
),
|
||||
.x86_64 => asm volatile (
|
||||
\\ .weak _DYNAMIC
|
||||
\\ .hidden _DYNAMIC
|
||||
\\ lea _DYNAMIC(%%rip), %[ret]
|
||||
: [ret] "=r" (-> [*]elf.Dyn)
|
||||
: [ret] "=r" (-> [*]elf.Dyn),
|
||||
),
|
||||
// Work around the limited offset range of `ldr`
|
||||
.arm => asm volatile (
|
||||
@ -47,7 +47,7 @@ fn getDynamicSymbol() [*]elf.Dyn {
|
||||
\\ b 2f
|
||||
\\ 1: .word _DYNAMIC-1b
|
||||
\\ 2:
|
||||
: [ret] "=r" (-> [*]elf.Dyn)
|
||||
: [ret] "=r" (-> [*]elf.Dyn),
|
||||
),
|
||||
// A simple `adr` is not enough as it has a limited offset range
|
||||
.aarch64 => asm volatile (
|
||||
@ -55,13 +55,13 @@ fn getDynamicSymbol() [*]elf.Dyn {
|
||||
\\ .hidden _DYNAMIC
|
||||
\\ adrp %[ret], _DYNAMIC
|
||||
\\ add %[ret], %[ret], #:lo12:_DYNAMIC
|
||||
: [ret] "=r" (-> [*]elf.Dyn)
|
||||
: [ret] "=r" (-> [*]elf.Dyn),
|
||||
),
|
||||
.riscv64 => asm volatile (
|
||||
\\ .weak _DYNAMIC
|
||||
\\ .hidden _DYNAMIC
|
||||
\\ lla %[ret], _DYNAMIC
|
||||
: [ret] "=r" (-> [*]elf.Dyn)
|
||||
: [ret] "=r" (-> [*]elf.Dyn),
|
||||
),
|
||||
else => {
|
||||
@compileError("PIE startup is not yet supported for this target!");
|
||||
|
||||
@ -15,8 +15,8 @@ pub fn syscall0(number: SYS) usize {
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [tmp] "{r1}" (buf)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r1}" (buf),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -30,9 +30,9 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r1}" (buf),
|
||||
[arg1] "{r0}" (arg1)
|
||||
[arg1] "{r0}" (arg1),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -46,10 +46,10 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r2}" (buf),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2)
|
||||
[arg2] "{r1}" (arg2),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -63,11 +63,11 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r3}" (buf),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3)
|
||||
[arg3] "{r2}" (arg3),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -81,12 +81,12 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r4}" (buf),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4)
|
||||
[arg4] "{r3}" (arg4),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -100,13 +100,13 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r5}" (buf),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4),
|
||||
[arg5] "{r4}" (arg5)
|
||||
[arg5] "{r4}" (arg5),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -128,14 +128,14 @@ pub fn syscall6(
|
||||
\\ ldr r7, [%[tmp]]
|
||||
\\ svc #0
|
||||
\\ ldr r7, [%[tmp], #4]
|
||||
: [ret] "={r0}" (-> usize)
|
||||
: [ret] "={r0}" (-> usize),
|
||||
: [tmp] "{r6}" (buf),
|
||||
[arg1] "{r0}" (arg1),
|
||||
[arg2] "{r1}" (arg2),
|
||||
[arg3] "{r2}" (arg3),
|
||||
[arg4] "{r3}" (arg4),
|
||||
[arg5] "{r4}" (arg5),
|
||||
[arg6] "{r5}" (arg6)
|
||||
[arg6] "{r5}" (arg6),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -148,7 +148,7 @@ pub fn restore() callconv(.Naked) void {
|
||||
\\ mov r7, %[number]
|
||||
\\ svc #0
|
||||
:
|
||||
: [number] "I" (@enumToInt(SYS.sigreturn))
|
||||
: [number] "I" (@enumToInt(SYS.sigreturn)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ pub fn restore_rt() callconv(.Naked) void {
|
||||
\\ mov r7, %[number]
|
||||
\\ svc #0
|
||||
:
|
||||
: [number] "I" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "I" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ pub fn setThreadPointer(addr: usize) void {
|
||||
// Update the %gs selector
|
||||
asm volatile ("movl %[gs_val], %%gs"
|
||||
:
|
||||
: [gs_val] "r" (gdt_entry_number << 3 | 3)
|
||||
: [gs_val] "r" (gdt_entry_number << 3 | 3),
|
||||
);
|
||||
},
|
||||
.x86_64 => {
|
||||
@ -142,7 +142,7 @@ pub fn setThreadPointer(addr: usize) void {
|
||||
asm volatile (
|
||||
\\ msr tpidr_el0, %[addr]
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.arm, .thumb => {
|
||||
@ -153,7 +153,7 @@ pub fn setThreadPointer(addr: usize) void {
|
||||
asm volatile (
|
||||
\\ mv tp, %[addr]
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.mips, .mipsel => {
|
||||
@ -164,21 +164,21 @@ pub fn setThreadPointer(addr: usize) void {
|
||||
asm volatile (
|
||||
\\ mr 2, %[addr]
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.powerpc64, .powerpc64le => {
|
||||
asm volatile (
|
||||
\\ mr 13, %[addr]
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
.sparcv9 => {
|
||||
asm volatile (
|
||||
\\ mov %[addr], %%g7
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
},
|
||||
else => @compileError("Unsupported architecture"),
|
||||
|
||||
@ -2,63 +2,63 @@ usingnamespace @import("../bits/linux.zig");
|
||||
|
||||
pub fn syscall0(number: SYS) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [number] "{rax}" (@enumToInt(number))
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall1(number: SYS, arg1: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1)
|
||||
[arg1] "{rdi}" (arg1),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2)
|
||||
[arg2] "{rsi}" (arg2),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3)
|
||||
[arg3] "{rdx}" (arg3),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3),
|
||||
[arg4] "{r10}" (arg4)
|
||||
[arg4] "{r10}" (arg4),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3),
|
||||
[arg4] "{r10}" (arg4),
|
||||
[arg5] "{r8}" (arg5)
|
||||
[arg5] "{r8}" (arg5),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
@ -73,14 +73,14 @@ pub fn syscall6(
|
||||
arg6: usize,
|
||||
) usize {
|
||||
return asm volatile ("syscall"
|
||||
: [ret] "={rax}" (-> usize)
|
||||
: [ret] "={rax}" (-> usize),
|
||||
: [number] "{rax}" (@enumToInt(number)),
|
||||
[arg1] "{rdi}" (arg1),
|
||||
[arg2] "{rsi}" (arg2),
|
||||
[arg3] "{rdx}" (arg3),
|
||||
[arg4] "{r10}" (arg4),
|
||||
[arg5] "{r8}" (arg5),
|
||||
[arg6] "{r9}" (arg6)
|
||||
[arg6] "{r9}" (arg6),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
@ -93,7 +93,7 @@ pub const restore = restore_rt;
|
||||
pub fn restore_rt() callconv(.Naked) void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rax}" (@enumToInt(SYS.rt_sigreturn))
|
||||
: [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1723,15 +1723,15 @@ pub fn teb() *TEB {
|
||||
return switch (builtin.target.cpu.arch) {
|
||||
.i386 => asm volatile (
|
||||
\\ movl %%fs:0x18, %[ptr]
|
||||
: [ptr] "=r" (-> *TEB)
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
),
|
||||
.x86_64 => asm volatile (
|
||||
\\ movq %%gs:0x30, %[ptr]
|
||||
: [ptr] "=r" (-> *TEB)
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
),
|
||||
.aarch64 => asm volatile (
|
||||
\\ mov %[ptr], x18
|
||||
: [ptr] "=r" (-> *TEB)
|
||||
: [ptr] "=r" (-> *TEB),
|
||||
),
|
||||
else => @compileError("unsupported arch"),
|
||||
};
|
||||
|
||||
@ -245,6 +245,13 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void
|
||||
});
|
||||
defer allocator.free(name);
|
||||
try out_stream.print("{s:<30} {s}\n", .{ name, option.description });
|
||||
if (option.enum_options) |enum_options| {
|
||||
const padding = " " ** 33;
|
||||
try out_stream.writeAll(padding ++ "Supported Values:\n");
|
||||
for (enum_options) |enum_option| {
|
||||
try out_stream.print(padding ++ " {s}\n", .{enum_option});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
||||
asm volatile (
|
||||
\\mrs %[x], ctr_el0
|
||||
\\
|
||||
: [x] "=r" (ctr_el0)
|
||||
: [x] "=r" (ctr_el0),
|
||||
);
|
||||
// The DC and IC instructions must use 64-bit registers so we don't use
|
||||
// uintptr_t in case this runs in an IPL32 environment.
|
||||
@ -101,7 +101,7 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
||||
while (addr < end) : (addr += dcache_line_size) {
|
||||
asm volatile ("dc cvau, %[addr]"
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -114,7 +114,7 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
||||
while (addr < end) : (addr += icache_line_size) {
|
||||
asm volatile ("ic ivau, %[addr]"
|
||||
:
|
||||
: [addr] "r" (addr)
|
||||
: [addr] "r" (addr),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ fn exit2(code: usize) noreturn {
|
||||
asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rax}" (231),
|
||||
[arg1] "{rdi}" (code)
|
||||
[arg1] "{rdi}" (code),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
},
|
||||
@ -106,7 +106,7 @@ fn exit2(code: usize) noreturn {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (1),
|
||||
[arg1] "{r0}" (code)
|
||||
[arg1] "{r0}" (code),
|
||||
: "memory"
|
||||
);
|
||||
},
|
||||
@ -114,7 +114,7 @@ fn exit2(code: usize) noreturn {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{x8}" (93),
|
||||
[arg1] "{x0}" (code)
|
||||
[arg1] "{x0}" (code),
|
||||
: "memory", "cc"
|
||||
);
|
||||
},
|
||||
@ -128,7 +128,7 @@ fn exit2(code: usize) noreturn {
|
||||
\\push $0
|
||||
\\syscall
|
||||
:
|
||||
: [syscall_number] "{rbp}" (8)
|
||||
: [syscall_number] "{rbp}" (8),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
},
|
||||
@ -137,7 +137,7 @@ fn exit2(code: usize) noreturn {
|
||||
.aarch64 => {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [exit] "{x0}" (0x08)
|
||||
: [exit] "{x0}" (0x08),
|
||||
: "memory", "cc"
|
||||
);
|
||||
},
|
||||
@ -208,34 +208,34 @@ fn _start() callconv(.Naked) noreturn {
|
||||
.x86_64 => {
|
||||
argc_argv_ptr = asm volatile (
|
||||
\\ xor %%rbp, %%rbp
|
||||
: [argc] "={rsp}" (-> [*]usize)
|
||||
: [argc] "={rsp}" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
.i386 => {
|
||||
argc_argv_ptr = asm volatile (
|
||||
\\ xor %%ebp, %%ebp
|
||||
: [argc] "={esp}" (-> [*]usize)
|
||||
: [argc] "={esp}" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
.aarch64, .aarch64_be, .arm, .armeb, .thumb => {
|
||||
argc_argv_ptr = asm volatile (
|
||||
\\ mov fp, #0
|
||||
\\ mov lr, #0
|
||||
: [argc] "={sp}" (-> [*]usize)
|
||||
: [argc] "={sp}" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
.riscv64 => {
|
||||
argc_argv_ptr = asm volatile (
|
||||
\\ li s0, 0
|
||||
\\ li ra, 0
|
||||
: [argc] "={sp}" (-> [*]usize)
|
||||
: [argc] "={sp}" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
.mips, .mipsel => {
|
||||
// The lr is already zeroed on entry, as specified by the ABI.
|
||||
argc_argv_ptr = asm volatile (
|
||||
\\ move $fp, $0
|
||||
: [argc] "={sp}" (-> [*]usize)
|
||||
: [argc] "={sp}" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
.powerpc => {
|
||||
@ -246,7 +246,7 @@ fn _start() callconv(.Naked) noreturn {
|
||||
\\ stwu 1,-16(1)
|
||||
\\ stw 0, 0(1)
|
||||
\\ mtlr 0
|
||||
: [argc] "={r4}" (-> [*]usize)
|
||||
: [argc] "={r4}" (-> [*]usize),
|
||||
:
|
||||
: "r0"
|
||||
);
|
||||
@ -259,7 +259,7 @@ fn _start() callconv(.Naked) noreturn {
|
||||
\\ li 0, 0
|
||||
\\ stdu 0, -32(1)
|
||||
\\ mtlr 0
|
||||
: [argc] "={r4}" (-> [*]usize)
|
||||
: [argc] "={r4}" (-> [*]usize),
|
||||
:
|
||||
: "r0"
|
||||
);
|
||||
@ -269,7 +269,7 @@ fn _start() callconv(.Naked) noreturn {
|
||||
argc_argv_ptr = asm (
|
||||
\\ mov %%g0, %%i6
|
||||
\\ add %%o6, 2175, %[argc]
|
||||
: [argc] "=r" (-> [*]usize)
|
||||
: [argc] "=r" (-> [*]usize),
|
||||
);
|
||||
},
|
||||
else => @compileError("unsupported arch"),
|
||||
|
||||
@ -13,9 +13,9 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
|
||||
\\ roll $3, %%edi ; roll $13, %%edi
|
||||
\\ roll $29, %%edi ; roll $19, %%edi
|
||||
\\ xchgl %%ebx,%%ebx
|
||||
: [_] "={edx}" (-> usize)
|
||||
: [_] "={edx}" (-> usize),
|
||||
: [_] "{eax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
|
||||
[_] "0" (default)
|
||||
[_] "0" (default),
|
||||
: "cc", "memory"
|
||||
);
|
||||
},
|
||||
@ -24,9 +24,9 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
|
||||
\\ rolq $3, %%rdi ; rolq $13, %%rdi
|
||||
\\ rolq $61, %%rdi ; rolq $51, %%rdi
|
||||
\\ xchgq %%rbx,%%rbx
|
||||
: [_] "={rdx}" (-> usize)
|
||||
: [_] "={rdx}" (-> usize),
|
||||
: [_] "{rax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
|
||||
[_] "0" (default)
|
||||
[_] "0" (default),
|
||||
: "cc", "memory"
|
||||
);
|
||||
},
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
test "zig fmt: preserves clobbers in inline asm with stray comma" {
|
||||
try testTransform(
|
||||
try testCanonical(
|
||||
\\fn foo() void {
|
||||
\\ asm volatile (""
|
||||
\\ : [_] "" (-> type),
|
||||
@ -13,20 +13,6 @@ test "zig fmt: preserves clobbers in inline asm with stray comma" {
|
||||
\\ );
|
||||
\\}
|
||||
\\
|
||||
,
|
||||
\\fn foo() void {
|
||||
\\ asm volatile (""
|
||||
\\ : [_] "" (-> type)
|
||||
\\ :
|
||||
\\ : "clobber"
|
||||
\\ );
|
||||
\\ asm volatile (""
|
||||
\\ :
|
||||
\\ : [_] "" (type)
|
||||
\\ : "clobber"
|
||||
\\ );
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
@ -508,15 +494,15 @@ test "zig fmt: asm expression with comptime content" {
|
||||
\\pub fn main() void {
|
||||
\\ asm volatile ("foo" ++ "bar");
|
||||
\\ asm volatile ("foo" ++ "bar"
|
||||
\\ : [_] "" (x)
|
||||
\\ : [_] "" (x),
|
||||
\\ );
|
||||
\\ asm volatile ("foo" ++ "bar"
|
||||
\\ : [_] "" (x)
|
||||
\\ : [_] "" (y)
|
||||
\\ : [_] "" (x),
|
||||
\\ : [_] "" (y),
|
||||
\\ );
|
||||
\\ asm volatile ("foo" ++ "bar"
|
||||
\\ : [_] "" (x)
|
||||
\\ : [_] "" (y)
|
||||
\\ : [_] "" (x),
|
||||
\\ : [_] "" (y),
|
||||
\\ : "h", "e", "l", "l", "o"
|
||||
\\ );
|
||||
\\}
|
||||
@ -2058,11 +2044,11 @@ test "zig fmt: simple asm" {
|
||||
\\ );
|
||||
\\
|
||||
\\ asm ("not real assembly"
|
||||
\\ : [a] "x" (x)
|
||||
\\ : [a] "x" (x),
|
||||
\\ );
|
||||
\\ asm ("not real assembly"
|
||||
\\ : [a] "x" (-> i32)
|
||||
\\ : [a] "x" (1)
|
||||
\\ : [a] "x" (-> i32),
|
||||
\\ : [a] "x" (1),
|
||||
\\ );
|
||||
\\ asm ("still not real assembly" ::: "a", "b");
|
||||
\\}
|
||||
@ -3712,9 +3698,9 @@ test "zig fmt: inline asm" {
|
||||
try testCanonical(
|
||||
\\pub fn syscall1(number: usize, arg1: usize) usize {
|
||||
\\ return asm volatile ("syscall"
|
||||
\\ : [ret] "={rax}" (-> usize)
|
||||
\\ : [ret] "={rax}" (-> usize),
|
||||
\\ : [number] "{rax}" (number),
|
||||
\\ [arg1] "{rdi}" (arg1)
|
||||
\\ [arg1] "{rdi}" (arg1),
|
||||
\\ : "rcx", "r11"
|
||||
\\ );
|
||||
\\}
|
||||
@ -3817,14 +3803,14 @@ test "zig fmt: inline asm parameter alignment" {
|
||||
\\ \\ foo
|
||||
\\ \\ bar
|
||||
\\ : [_] "" (-> usize),
|
||||
\\ [_] "" (-> usize)
|
||||
\\ [_] "" (-> usize),
|
||||
\\ );
|
||||
\\ asm volatile (
|
||||
\\ \\ foo
|
||||
\\ \\ bar
|
||||
\\ :
|
||||
\\ : [_] "" (0),
|
||||
\\ [_] "" (0)
|
||||
\\ [_] "" (0),
|
||||
\\ );
|
||||
\\ asm volatile (
|
||||
\\ \\ foo
|
||||
@ -3834,9 +3820,9 @@ test "zig fmt: inline asm parameter alignment" {
|
||||
\\ \\ foo
|
||||
\\ \\ bar
|
||||
\\ : [_] "" (-> usize),
|
||||
\\ [_] "" (-> usize)
|
||||
\\ [_] "" (-> usize),
|
||||
\\ : [_] "" (0),
|
||||
\\ [_] "" (0)
|
||||
\\ [_] "" (0),
|
||||
\\ : "", ""
|
||||
\\ );
|
||||
\\}
|
||||
|
||||
@ -1944,13 +1944,13 @@ fn renderAsm(
|
||||
try renderToken(ais, tree, comma, .newline); // ,
|
||||
try renderExtraNewlineToken(ais, tree, tree.firstToken(next_asm_output));
|
||||
} else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {
|
||||
try renderAsmOutput(gpa, ais, tree, asm_output, .newline);
|
||||
try renderAsmOutput(gpa, ais, tree, asm_output, .comma);
|
||||
ais.popIndent();
|
||||
ais.setIndentDelta(indent_delta);
|
||||
ais.popIndent();
|
||||
return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
|
||||
} else {
|
||||
try renderAsmOutput(gpa, ais, tree, asm_output, .newline);
|
||||
try renderAsmOutput(gpa, ais, tree, asm_output, .comma);
|
||||
const comma_or_colon = tree.lastToken(asm_output) + 1;
|
||||
ais.popIndent();
|
||||
break :colon2 switch (token_tags[comma_or_colon]) {
|
||||
@ -1976,13 +1976,13 @@ fn renderAsm(
|
||||
try renderToken(ais, tree, first_token - 1, .newline); // ,
|
||||
try renderExtraNewlineToken(ais, tree, first_token);
|
||||
} else if (asm_node.first_clobber == null) {
|
||||
try renderAsmInput(gpa, ais, tree, asm_input, .newline);
|
||||
try renderAsmInput(gpa, ais, tree, asm_input, .comma);
|
||||
ais.popIndent();
|
||||
ais.setIndentDelta(indent_delta);
|
||||
ais.popIndent();
|
||||
return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
|
||||
} else {
|
||||
try renderAsmInput(gpa, ais, tree, asm_input, .newline);
|
||||
try renderAsmInput(gpa, ais, tree, asm_input, .comma);
|
||||
const comma_or_colon = tree.lastToken(asm_input) + 1;
|
||||
ais.popIndent();
|
||||
break :colon3 switch (token_tags[comma_or_colon]) {
|
||||
|
||||
@ -543,7 +543,7 @@ fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf {
|
||||
:
|
||||
: [leaf_id] "{eax}" (leaf_id),
|
||||
[subid] "{ecx}" (subid),
|
||||
[leaf_ptr] "r" (&cpuid_leaf)
|
||||
[leaf_ptr] "r" (&cpuid_leaf),
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
|
||||
@ -555,7 +555,7 @@ fn getXCR0() u32 {
|
||||
return asm volatile (
|
||||
\\ xor %%ecx, %%ecx
|
||||
\\ xgetbv
|
||||
: [ret] "={eax}" (-> u32)
|
||||
: [ret] "={eax}" (-> u32),
|
||||
:
|
||||
: "eax", "edx", "ecx"
|
||||
);
|
||||
|
||||
275
src/AstGen.zig
275
src/AstGen.zig
@ -2883,8 +2883,6 @@ fn fnDecl(
|
||||
};
|
||||
const fn_name_str_index = try astgen.identAsString(fn_name_token);
|
||||
|
||||
try astgen.declareNewName(scope, fn_name_str_index, decl_node, fn_name_token);
|
||||
|
||||
// We insert this at the beginning so that its instruction index marks the
|
||||
// start of the top level declaration.
|
||||
const block_inst = try gz.addBlock(.block_inline, fn_proto.ast.proto_node);
|
||||
@ -3153,8 +3151,6 @@ fn globalVarDecl(
|
||||
const name_token = var_decl.ast.mut_token + 1;
|
||||
const name_str_index = try astgen.identAsString(name_token);
|
||||
|
||||
try astgen.declareNewName(scope, name_str_index, node, name_token);
|
||||
|
||||
var block_scope: GenZir = .{
|
||||
.parent = scope,
|
||||
.decl_node_index = node,
|
||||
@ -3509,9 +3505,11 @@ fn structDeclInner(
|
||||
};
|
||||
defer block_scope.instructions.deinit(gpa);
|
||||
|
||||
var namespace: Scope.Namespace = .{ .parent = scope };
|
||||
var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
|
||||
defer namespace.decls.deinit(gpa);
|
||||
|
||||
try astgen.scanDecls(&namespace, container_decl.ast.members);
|
||||
|
||||
var wip_decls: WipDecls = .{};
|
||||
defer wip_decls.deinit(gpa);
|
||||
|
||||
@ -3671,7 +3669,7 @@ fn structDeclInner(
|
||||
const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
|
||||
.none
|
||||
else
|
||||
try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
|
||||
try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
|
||||
fields_data.appendAssumeCapacity(@enumToInt(field_type));
|
||||
|
||||
known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);
|
||||
@ -3687,13 +3685,13 @@ fn structDeclInner(
|
||||
(@as(u32, @boolToInt(unused)) << 31);
|
||||
|
||||
if (have_align) {
|
||||
const align_inst = try expr(&block_scope, &block_scope.base, align_rl, member.ast.align_expr);
|
||||
const align_inst = try expr(&block_scope, &namespace.base, align_rl, member.ast.align_expr);
|
||||
fields_data.appendAssumeCapacity(@enumToInt(align_inst));
|
||||
}
|
||||
if (have_value) {
|
||||
const rl: ResultLoc = if (field_type == .none) .none else .{ .ty = field_type };
|
||||
|
||||
const default_inst = try expr(&block_scope, &block_scope.base, rl, member.ast.value_expr);
|
||||
const default_inst = try expr(&block_scope, &namespace.base, rl, member.ast.value_expr);
|
||||
fields_data.appendAssumeCapacity(@enumToInt(default_inst));
|
||||
} else if (member.comptime_token) |comptime_token| {
|
||||
return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
|
||||
@ -3756,7 +3754,7 @@ fn unionDeclInner(
|
||||
node: ast.Node.Index,
|
||||
members: []const ast.Node.Index,
|
||||
layout: std.builtin.TypeInfo.ContainerLayout,
|
||||
arg_inst: Zir.Inst.Ref,
|
||||
arg_node: ast.Node.Index,
|
||||
have_auto_enum: bool,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
@ -3778,9 +3776,16 @@ fn unionDeclInner(
|
||||
};
|
||||
defer block_scope.instructions.deinit(gpa);
|
||||
|
||||
var namespace: Scope.Namespace = .{ .parent = scope };
|
||||
var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
|
||||
defer namespace.decls.deinit(gpa);
|
||||
|
||||
try astgen.scanDecls(&namespace, members);
|
||||
|
||||
const arg_inst: Zir.Inst.Ref = if (arg_node != 0)
|
||||
try typeExpr(gz, &namespace.base, arg_node)
|
||||
else
|
||||
.none;
|
||||
|
||||
var wip_decls: WipDecls = .{};
|
||||
defer wip_decls.deinit(gpa);
|
||||
|
||||
@ -3946,7 +3951,7 @@ fn unionDeclInner(
|
||||
(@as(u32, @boolToInt(unused)) << 31);
|
||||
|
||||
if (have_type and node_tags[member.ast.type_expr] != .@"anytype") {
|
||||
const field_type = try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
|
||||
const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
|
||||
fields_data.appendAssumeCapacity(@enumToInt(field_type));
|
||||
}
|
||||
if (have_align) {
|
||||
@ -4046,11 +4051,6 @@ fn containerDecl(
|
||||
// We must not create any types until Sema. Here the goal is only to generate
|
||||
// ZIR for all the field types, alignments, and default value expressions.
|
||||
|
||||
const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
|
||||
try comptimeExpr(gz, scope, .{ .ty = .type_type }, container_decl.ast.arg)
|
||||
else
|
||||
.none;
|
||||
|
||||
switch (token_tags[container_decl.ast.main_token]) {
|
||||
.keyword_struct => {
|
||||
const layout = if (container_decl.layout_token) |t| switch (token_tags[t]) {
|
||||
@ -4059,7 +4059,7 @@ fn containerDecl(
|
||||
else => unreachable,
|
||||
} else std.builtin.TypeInfo.ContainerLayout.Auto;
|
||||
|
||||
assert(arg_inst == .none);
|
||||
assert(container_decl.ast.arg == 0);
|
||||
|
||||
const result = try structDeclInner(gz, scope, node, container_decl, layout);
|
||||
return rvalue(gz, rl, result, node);
|
||||
@ -4073,7 +4073,7 @@ fn containerDecl(
|
||||
|
||||
const have_auto_enum = container_decl.ast.enum_token != null;
|
||||
|
||||
const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, arg_inst, have_auto_enum);
|
||||
const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, have_auto_enum);
|
||||
return rvalue(gz, rl, result, node);
|
||||
},
|
||||
.keyword_enum => {
|
||||
@ -4140,7 +4140,7 @@ fn containerDecl(
|
||||
}
|
||||
total_fields += 1;
|
||||
if (member.ast.value_expr != 0) {
|
||||
if (arg_inst == .none) {
|
||||
if (container_decl.ast.arg == 0) {
|
||||
return astgen.failNode(member.ast.value_expr, "value assigned to enum tag with inferred tag type", .{});
|
||||
}
|
||||
values += 1;
|
||||
@ -4159,7 +4159,7 @@ fn containerDecl(
|
||||
// must be at least one tag.
|
||||
return astgen.failNode(node, "enum declarations must have at least one tag", .{});
|
||||
}
|
||||
if (counts.nonexhaustive_node != 0 and arg_inst == .none) {
|
||||
if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) {
|
||||
return astgen.failNodeNotes(
|
||||
node,
|
||||
"non-exhaustive enum missing integer tag type",
|
||||
@ -4189,9 +4189,16 @@ fn containerDecl(
|
||||
};
|
||||
defer block_scope.instructions.deinit(gpa);
|
||||
|
||||
var namespace: Scope.Namespace = .{ .parent = scope };
|
||||
var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
|
||||
defer namespace.decls.deinit(gpa);
|
||||
|
||||
try astgen.scanDecls(&namespace, container_decl.ast.members);
|
||||
|
||||
const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
|
||||
try comptimeExpr(gz, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg)
|
||||
else
|
||||
.none;
|
||||
|
||||
var wip_decls: WipDecls = .{};
|
||||
defer wip_decls.deinit(gpa);
|
||||
|
||||
@ -4364,7 +4371,7 @@ fn containerDecl(
|
||||
},
|
||||
);
|
||||
}
|
||||
const tag_value_inst = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
|
||||
const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .ty = arg_inst }, member.ast.value_expr);
|
||||
fields_data.appendAssumeCapacity(@enumToInt(tag_value_inst));
|
||||
}
|
||||
|
||||
@ -4416,9 +4423,13 @@ fn containerDecl(
|
||||
return rvalue(gz, rl, indexToRef(decl_inst), node);
|
||||
},
|
||||
.keyword_opaque => {
|
||||
var namespace: Scope.Namespace = .{ .parent = scope };
|
||||
assert(container_decl.ast.arg == 0);
|
||||
|
||||
var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
|
||||
defer namespace.decls.deinit(gpa);
|
||||
|
||||
try astgen.scanDecls(&namespace, container_decl.ast.members);
|
||||
|
||||
var wip_decls: WipDecls = .{};
|
||||
defer wip_decls.deinit(gpa);
|
||||
|
||||
@ -6352,73 +6363,63 @@ fn identifier(
|
||||
|
||||
// Local variables, including function parameters.
|
||||
const name_str_index = try astgen.identAsString(ident_token);
|
||||
{
|
||||
var s = scope;
|
||||
var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
|
||||
var hit_namespace = false;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
var s = scope;
|
||||
var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
|
||||
var hit_namespace: ast.Node.Index = 0;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
|
||||
if (local_val.name == name_str_index) {
|
||||
local_val.used = true;
|
||||
// Captures of non-locals need to be emitted as decl_val or decl_ref.
|
||||
// This *might* be capturable depending on if it is comptime known.
|
||||
if (!hit_namespace) {
|
||||
return rvalue(gz, rl, local_val.inst, ident);
|
||||
}
|
||||
if (local_val.name == name_str_index) {
|
||||
local_val.used = true;
|
||||
// Locals cannot shadow anything, so we do not need to look for ambiguous
|
||||
// references in this case.
|
||||
return rvalue(gz, rl, local_val.inst, ident);
|
||||
}
|
||||
s = local_val.parent;
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
if (local_ptr.name == name_str_index) {
|
||||
local_ptr.used = true;
|
||||
if (hit_namespace != 0 and !local_ptr.maybe_comptime) {
|
||||
return astgen.failNodeNotes(ident, "mutable '{s}' not accessible from here", .{ident_name}, &.{
|
||||
try astgen.errNoteTok(local_ptr.token_src, "declared mutable here", .{}),
|
||||
try astgen.errNoteNode(hit_namespace, "crosses namespace boundary here", .{}),
|
||||
});
|
||||
}
|
||||
s = local_val.parent;
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
if (local_ptr.name == name_str_index) {
|
||||
local_ptr.used = true;
|
||||
if (hit_namespace) {
|
||||
if (local_ptr.maybe_comptime)
|
||||
break
|
||||
else
|
||||
return astgen.failNodeNotes(ident, "'{s}' not accessible from inner function", .{ident_name}, &.{
|
||||
try astgen.errNoteTok(local_ptr.token_src, "declared here", .{}),
|
||||
// TODO add crossed function definition here note.
|
||||
// Maybe add a note to the error about it being because of the var,
|
||||
// maybe recommend copying it into a const variable. -SpexGuy
|
||||
});
|
||||
}
|
||||
switch (rl) {
|
||||
.ref, .none_or_ref => return local_ptr.ptr,
|
||||
else => {
|
||||
const loaded = try gz.addUnNode(.load, local_ptr.ptr, ident);
|
||||
return rvalue(gz, rl, loaded, ident);
|
||||
},
|
||||
}
|
||||
switch (rl) {
|
||||
.ref, .none_or_ref => return local_ptr.ptr,
|
||||
else => {
|
||||
const loaded = try gz.addUnNode(.load, local_ptr.ptr, ident);
|
||||
return rvalue(gz, rl, loaded, ident);
|
||||
},
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
// look for ambiguous references to decls
|
||||
.namespace => {
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
if (ns.decls.get(name_str_index)) |i| {
|
||||
if (found_already) |f|
|
||||
return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
|
||||
try astgen.errNoteNode(i, "declared here", .{}),
|
||||
try astgen.errNoteNode(f, "also declared here", .{}),
|
||||
})
|
||||
else
|
||||
found_already = i;
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.namespace => {
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
if (ns.decls.get(name_str_index)) |i| {
|
||||
if (found_already) |f| {
|
||||
return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
|
||||
try astgen.errNoteNode(f, "declared here", .{}),
|
||||
try astgen.errNoteNode(i, "also declared here", .{}),
|
||||
});
|
||||
}
|
||||
hit_namespace = true;
|
||||
s = ns.parent;
|
||||
},
|
||||
.top => break,
|
||||
};
|
||||
}
|
||||
// We found a match but must continue looking for ambiguous references to decls.
|
||||
found_already = i;
|
||||
}
|
||||
hit_namespace = ns.node;
|
||||
s = ns.parent;
|
||||
},
|
||||
.top => break,
|
||||
};
|
||||
|
||||
// We can't look up Decls until Sema because the same ZIR code is supposed to be
|
||||
// used for multiple generic instantiations, and this may refer to a different Decl
|
||||
// depending on the scope, determined by the generic instantiation.
|
||||
// Decl references happen by name rather than ZIR index so that when unrelated
|
||||
// decls are modified, ZIR code containing references to them can be unmodified.
|
||||
switch (rl) {
|
||||
.ref, .none_or_ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token),
|
||||
else => {
|
||||
@ -8383,7 +8384,7 @@ fn nodeImpliesRuntimeBits(tree: *const ast.Tree, start_node: ast.Node.Index) boo
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies `rl` semantics to `inst`. Expressions which do not do their own handling of
|
||||
/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
|
||||
/// result locations must call this function on their result.
|
||||
/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.
|
||||
/// If the `ResultLoc` is `ty`, it will coerce the result to the type.
|
||||
@ -8393,6 +8394,7 @@ fn rvalue(
|
||||
result: Zir.Inst.Ref,
|
||||
src_node: ast.Node.Index,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
if (gz.endsWithNoReturn()) return result;
|
||||
switch (rl) {
|
||||
.none, .none_or_ref, .coerced_ty => return result,
|
||||
.discard => {
|
||||
@ -8941,6 +8943,7 @@ const Scope = struct {
|
||||
/// Maps string table index to the source location of declaration,
|
||||
/// for the purposes of reporting name shadowing compile errors.
|
||||
decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},
|
||||
node: ast.Node.Index,
|
||||
};
|
||||
|
||||
const Top = struct {
|
||||
@ -10014,53 +10017,6 @@ fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {
|
||||
return @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + index;
|
||||
}
|
||||
|
||||
fn declareNewName(
|
||||
astgen: *AstGen,
|
||||
start_scope: *Scope,
|
||||
name_index: u32,
|
||||
node: ast.Node.Index,
|
||||
name_token: ast.TokenIndex,
|
||||
) !void {
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
const token_bytes = astgen.tree.tokenSlice(name_token);
|
||||
if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
|
||||
return astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
|
||||
token_bytes,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
|
||||
token_bytes,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
var scope = start_scope;
|
||||
while (true) {
|
||||
switch (scope.tag) {
|
||||
.gen_zir => scope = scope.cast(GenZir).?.parent,
|
||||
.local_val => scope = scope.cast(Scope.LocalVal).?.parent,
|
||||
.local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
|
||||
.defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
|
||||
.namespace => {
|
||||
const ns = scope.cast(Scope.Namespace).?;
|
||||
const gop = try ns.decls.getOrPut(gpa, name_index);
|
||||
if (gop.found_existing) {
|
||||
const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_index)));
|
||||
defer gpa.free(name);
|
||||
return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{
|
||||
name,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteNode(gop.value_ptr.*, "other declaration here", .{}),
|
||||
});
|
||||
}
|
||||
gop.value_ptr.* = node;
|
||||
break;
|
||||
},
|
||||
.top => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn isPrimitive(name: []const u8) bool {
|
||||
if (simple_types.get(name) != null) return true;
|
||||
if (name.len < 2) return false;
|
||||
@ -10183,3 +10139,56 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const ast.Node.Index) !void {
|
||||
const gpa = astgen.gpa;
|
||||
const tree = astgen.tree;
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
for (members) |member_node| {
|
||||
const name_token = switch (node_tags[member_node]) {
|
||||
.fn_decl,
|
||||
.fn_proto_simple,
|
||||
.fn_proto_multi,
|
||||
.fn_proto_one,
|
||||
.fn_proto,
|
||||
.global_var_decl,
|
||||
.local_var_decl,
|
||||
.simple_var_decl,
|
||||
.aligned_var_decl,
|
||||
=> main_tokens[member_node] + 1,
|
||||
|
||||
else => continue,
|
||||
};
|
||||
|
||||
const token_bytes = astgen.tree.tokenSlice(name_token);
|
||||
if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
|
||||
switch (astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
|
||||
token_bytes,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
|
||||
token_bytes,
|
||||
}),
|
||||
})) {
|
||||
error.AnalysisFail => continue,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
}
|
||||
}
|
||||
|
||||
const name_str_index = try astgen.identAsString(name_token);
|
||||
const gop = try namespace.decls.getOrPut(gpa, name_str_index);
|
||||
if (gop.found_existing) {
|
||||
const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_str_index)));
|
||||
defer gpa.free(name);
|
||||
switch (astgen.failNodeNotes(member_node, "redeclaration of '{s}'", .{
|
||||
name,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteNode(gop.value_ptr.*, "other declaration here", .{}),
|
||||
})) {
|
||||
error.AnalysisFail => continue,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
}
|
||||
}
|
||||
gop.value_ptr.* = member_node;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2648,7 +2648,10 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
|
||||
undefined;
|
||||
defer if (data_has_safety_tag) gpa.free(safety_buffer);
|
||||
const data_ptr = if (data_has_safety_tag)
|
||||
@ptrCast([*]const u8, safety_buffer.ptr)
|
||||
if (file.zir.instructions.len == 0)
|
||||
@as([*]const u8, undefined)
|
||||
else
|
||||
@ptrCast([*]const u8, safety_buffer.ptr)
|
||||
else
|
||||
@ptrCast([*]const u8, file.zir.instructions.items(.data).ptr);
|
||||
if (data_has_safety_tag) {
|
||||
|
||||
@ -5210,25 +5210,59 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
usingnamespace switch (arch) {
|
||||
.i386 => @import("codegen/x86.zig"),
|
||||
.x86_64 => @import("codegen/x86_64.zig"),
|
||||
.riscv64 => @import("codegen/riscv64.zig"),
|
||||
.arm, .armeb => @import("codegen/arm.zig"),
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig"),
|
||||
else => struct {
|
||||
pub const Register = enum {
|
||||
dummy,
|
||||
const Register = switch (arch) {
|
||||
.i386 => @import("codegen/x86.zig").Register,
|
||||
.x86_64 => @import("codegen/x86_64.zig").Register,
|
||||
.riscv64 => @import("codegen/riscv64.zig").Register,
|
||||
.arm, .armeb => @import("codegen/arm.zig").Register,
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").Register,
|
||||
else => enum {
|
||||
dummy,
|
||||
|
||||
pub fn allocIndex(self: Register) ?u4 {
|
||||
_ = self;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
pub const callee_preserved_regs = [_]Register{};
|
||||
pub fn allocIndex(self: Register) ?u4 {
|
||||
_ = self;
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const Instruction = switch (arch) {
|
||||
.riscv64 => @import("codegen/riscv64.zig").Instruction,
|
||||
.arm, .armeb => @import("codegen/arm.zig").Instruction,
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").Instruction,
|
||||
else => void,
|
||||
};
|
||||
|
||||
const Condition = switch (arch) {
|
||||
.arm, .armeb => @import("codegen/arm.zig").Condition,
|
||||
else => void,
|
||||
};
|
||||
|
||||
const callee_preserved_regs = switch (arch) {
|
||||
.i386 => @import("codegen/x86.zig").callee_preserved_regs,
|
||||
.x86_64 => @import("codegen/x86_64.zig").callee_preserved_regs,
|
||||
.riscv64 => @import("codegen/riscv64.zig").callee_preserved_regs,
|
||||
.arm, .armeb => @import("codegen/arm.zig").callee_preserved_regs,
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").callee_preserved_regs,
|
||||
else => [_]Register{},
|
||||
};
|
||||
|
||||
const c_abi_int_param_regs = switch (arch) {
|
||||
.i386 => @import("codegen/x86.zig").c_abi_int_param_regs,
|
||||
.x86_64 => @import("codegen/x86_64.zig").c_abi_int_param_regs,
|
||||
.arm, .armeb => @import("codegen/arm.zig").c_abi_int_param_regs,
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").c_abi_int_param_regs,
|
||||
else => [_]Register{},
|
||||
};
|
||||
|
||||
const c_abi_int_return_regs = switch (arch) {
|
||||
.i386 => @import("codegen/x86.zig").c_abi_int_return_regs,
|
||||
.x86_64 => @import("codegen/x86_64.zig").c_abi_int_return_regs,
|
||||
.arm, .armeb => @import("codegen/arm.zig").c_abi_int_return_regs,
|
||||
.aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").c_abi_int_return_regs,
|
||||
else => [_]Register{},
|
||||
};
|
||||
|
||||
fn parseRegName(name: []const u8) ?Register {
|
||||
if (@hasDecl(Register, "parseRegName")) {
|
||||
return Register.parseRegName(name);
|
||||
|
||||
@ -886,11 +886,11 @@ pub const Instruction = union(enum) {
|
||||
return dataProcessing(cond, .mov, 1, rd, .r0, op2);
|
||||
}
|
||||
|
||||
pub fn bic(cond: Condition, rd: Register, op2: Operand) Instruction {
|
||||
pub fn bic(cond: Condition, rd: Register, rn: Register, op2: Operand) Instruction {
|
||||
return dataProcessing(cond, .bic, 0, rd, rn, op2);
|
||||
}
|
||||
|
||||
pub fn bics(cond: Condition, rd: Register, op2: Operand) Instruction {
|
||||
pub fn bics(cond: Condition, rd: Register, rn: Register, op2: Operand) Instruction {
|
||||
return dataProcessing(cond, .bic, 1, rd, rn, op2);
|
||||
}
|
||||
|
||||
|
||||
@ -169,7 +169,7 @@ pub const Object = struct {
|
||||
const context = llvm.Context.create();
|
||||
errdefer context.dispose();
|
||||
|
||||
initializeLLVMTargets();
|
||||
initializeLLVMTarget(options.target.cpu.arch);
|
||||
|
||||
const root_nameZ = try gpa.dupeZ(u8, options.root_name);
|
||||
defer gpa.free(root_nameZ);
|
||||
@ -258,14 +258,6 @@ pub const Object = struct {
|
||||
gpa.destroy(self);
|
||||
}
|
||||
|
||||
fn initializeLLVMTargets() void {
|
||||
llvm.initializeAllTargets();
|
||||
llvm.initializeAllTargetInfos();
|
||||
llvm.initializeAllTargetMCs();
|
||||
llvm.initializeAllAsmPrinters();
|
||||
llvm.initializeAllAsmParsers();
|
||||
}
|
||||
|
||||
fn locPath(
|
||||
arena: *Allocator,
|
||||
opt_loc: ?Compilation.EmitLoc,
|
||||
@ -1960,3 +1952,144 @@ pub const FuncGen = struct {
|
||||
return self.llvmModule().getIntrinsicDeclaration(id, null, 0);
|
||||
}
|
||||
};
|
||||
|
||||
fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
|
||||
switch (arch) {
|
||||
.aarch64, .aarch64_be, .aarch64_32 => {
|
||||
llvm.LLVMInitializeAArch64Target();
|
||||
llvm.LLVMInitializeAArch64TargetInfo();
|
||||
llvm.LLVMInitializeAArch64TargetMC();
|
||||
llvm.LLVMInitializeAArch64AsmPrinter();
|
||||
llvm.LLVMInitializeAArch64AsmParser();
|
||||
},
|
||||
.amdgcn => {
|
||||
llvm.LLVMInitializeAMDGPUTarget();
|
||||
llvm.LLVMInitializeAMDGPUTargetInfo();
|
||||
llvm.LLVMInitializeAMDGPUTargetMC();
|
||||
llvm.LLVMInitializeAMDGPUAsmPrinter();
|
||||
llvm.LLVMInitializeAMDGPUAsmParser();
|
||||
},
|
||||
.arm, .armeb => {
|
||||
llvm.LLVMInitializeARMTarget();
|
||||
llvm.LLVMInitializeARMTargetInfo();
|
||||
llvm.LLVMInitializeARMTargetMC();
|
||||
llvm.LLVMInitializeARMAsmPrinter();
|
||||
llvm.LLVMInitializeARMAsmParser();
|
||||
},
|
||||
.avr => {
|
||||
llvm.LLVMInitializeAVRTarget();
|
||||
llvm.LLVMInitializeAVRTargetInfo();
|
||||
llvm.LLVMInitializeAVRTargetMC();
|
||||
llvm.LLVMInitializeAVRAsmPrinter();
|
||||
llvm.LLVMInitializeAVRAsmParser();
|
||||
},
|
||||
.bpfel, .bpfeb => {
|
||||
llvm.LLVMInitializeBPFTarget();
|
||||
llvm.LLVMInitializeBPFTargetInfo();
|
||||
llvm.LLVMInitializeBPFTargetMC();
|
||||
llvm.LLVMInitializeBPFAsmPrinter();
|
||||
llvm.LLVMInitializeBPFAsmParser();
|
||||
},
|
||||
.hexagon => {
|
||||
llvm.LLVMInitializeHexagonTarget();
|
||||
llvm.LLVMInitializeHexagonTargetInfo();
|
||||
llvm.LLVMInitializeHexagonTargetMC();
|
||||
llvm.LLVMInitializeHexagonAsmPrinter();
|
||||
llvm.LLVMInitializeHexagonAsmParser();
|
||||
},
|
||||
.lanai => {
|
||||
llvm.LLVMInitializeLanaiTarget();
|
||||
llvm.LLVMInitializeLanaiTargetInfo();
|
||||
llvm.LLVMInitializeLanaiTargetMC();
|
||||
llvm.LLVMInitializeLanaiAsmPrinter();
|
||||
llvm.LLVMInitializeLanaiAsmParser();
|
||||
},
|
||||
.mips, .mipsel, .mips64, .mips64el => {
|
||||
llvm.LLVMInitializeMipsTarget();
|
||||
llvm.LLVMInitializeMipsTargetInfo();
|
||||
llvm.LLVMInitializeMipsTargetMC();
|
||||
llvm.LLVMInitializeMipsAsmPrinter();
|
||||
llvm.LLVMInitializeMipsAsmParser();
|
||||
},
|
||||
.msp430 => {
|
||||
llvm.LLVMInitializeMSP430Target();
|
||||
llvm.LLVMInitializeMSP430TargetInfo();
|
||||
llvm.LLVMInitializeMSP430TargetMC();
|
||||
llvm.LLVMInitializeMSP430AsmPrinter();
|
||||
llvm.LLVMInitializeMSP430AsmParser();
|
||||
},
|
||||
.nvptx, .nvptx64 => {
|
||||
llvm.LLVMInitializeNVPTXTarget();
|
||||
llvm.LLVMInitializeNVPTXTargetInfo();
|
||||
llvm.LLVMInitializeNVPTXTargetMC();
|
||||
llvm.LLVMInitializeNVPTXAsmPrinter();
|
||||
// There is no LLVMInitializeNVPTXAsmParser function available.
|
||||
},
|
||||
.powerpc, .powerpcle, .powerpc64, .powerpc64le => {
|
||||
llvm.LLVMInitializePowerPCTarget();
|
||||
llvm.LLVMInitializePowerPCTargetInfo();
|
||||
llvm.LLVMInitializePowerPCTargetMC();
|
||||
llvm.LLVMInitializePowerPCAsmPrinter();
|
||||
llvm.LLVMInitializePowerPCAsmParser();
|
||||
},
|
||||
.riscv32, .riscv64 => {
|
||||
llvm.LLVMInitializeRISCVTarget();
|
||||
llvm.LLVMInitializeRISCVTargetInfo();
|
||||
llvm.LLVMInitializeRISCVTargetMC();
|
||||
llvm.LLVMInitializeRISCVAsmPrinter();
|
||||
llvm.LLVMInitializeRISCVAsmParser();
|
||||
},
|
||||
.sparc, .sparcv9, .sparcel => {
|
||||
llvm.LLVMInitializeSparcTarget();
|
||||
llvm.LLVMInitializeSparcTargetInfo();
|
||||
llvm.LLVMInitializeSparcTargetMC();
|
||||
llvm.LLVMInitializeSparcAsmPrinter();
|
||||
llvm.LLVMInitializeSparcAsmParser();
|
||||
},
|
||||
.s390x => {
|
||||
llvm.LLVMInitializeSystemZTarget();
|
||||
llvm.LLVMInitializeSystemZTargetInfo();
|
||||
llvm.LLVMInitializeSystemZTargetMC();
|
||||
llvm.LLVMInitializeSystemZAsmPrinter();
|
||||
llvm.LLVMInitializeSystemZAsmParser();
|
||||
},
|
||||
.wasm32, .wasm64 => {
|
||||
llvm.LLVMInitializeWebAssemblyTarget();
|
||||
llvm.LLVMInitializeWebAssemblyTargetInfo();
|
||||
llvm.LLVMInitializeWebAssemblyTargetMC();
|
||||
llvm.LLVMInitializeWebAssemblyAsmPrinter();
|
||||
llvm.LLVMInitializeWebAssemblyAsmParser();
|
||||
},
|
||||
.i386, .x86_64 => {
|
||||
llvm.LLVMInitializeX86Target();
|
||||
llvm.LLVMInitializeX86TargetInfo();
|
||||
llvm.LLVMInitializeX86TargetMC();
|
||||
llvm.LLVMInitializeX86AsmPrinter();
|
||||
llvm.LLVMInitializeX86AsmParser();
|
||||
},
|
||||
.xcore => {
|
||||
llvm.LLVMInitializeXCoreTarget();
|
||||
llvm.LLVMInitializeXCoreTargetInfo();
|
||||
llvm.LLVMInitializeXCoreTargetMC();
|
||||
llvm.LLVMInitializeXCoreAsmPrinter();
|
||||
// There is no LLVMInitializeXCoreAsmParser function available.
|
||||
},
|
||||
.arc => {},
|
||||
.csky => {},
|
||||
.r600 => {},
|
||||
.tce, .tcele => {},
|
||||
.thumb, .thumbeb => {},
|
||||
.le32, .le64 => {},
|
||||
.amdil, .amdil64 => {},
|
||||
.hsail, .hsail64 => {},
|
||||
.spir, .spir64 => {},
|
||||
.kalimba => {},
|
||||
.shave => {},
|
||||
.renderscript32 => {},
|
||||
.renderscript64 => {},
|
||||
.ve => {},
|
||||
.spu_2 => {},
|
||||
.spirv32 => {},
|
||||
.spirv64 => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -597,188 +597,93 @@ pub const Target = opaque {
|
||||
extern fn LLVMGetTargetFromTriple(Triple: [*:0]const u8, T: **const Target, ErrorMessage: *[*:0]const u8) Bool;
|
||||
};
|
||||
|
||||
extern fn LLVMInitializeAArch64TargetInfo() void;
|
||||
extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
||||
extern fn LLVMInitializeARMTargetInfo() void;
|
||||
extern fn LLVMInitializeAVRTargetInfo() void;
|
||||
extern fn LLVMInitializeBPFTargetInfo() void;
|
||||
extern fn LLVMInitializeHexagonTargetInfo() void;
|
||||
extern fn LLVMInitializeLanaiTargetInfo() void;
|
||||
extern fn LLVMInitializeMipsTargetInfo() void;
|
||||
extern fn LLVMInitializeMSP430TargetInfo() void;
|
||||
extern fn LLVMInitializeNVPTXTargetInfo() void;
|
||||
extern fn LLVMInitializePowerPCTargetInfo() void;
|
||||
extern fn LLVMInitializeRISCVTargetInfo() void;
|
||||
extern fn LLVMInitializeSparcTargetInfo() void;
|
||||
extern fn LLVMInitializeSystemZTargetInfo() void;
|
||||
extern fn LLVMInitializeWebAssemblyTargetInfo() void;
|
||||
extern fn LLVMInitializeX86TargetInfo() void;
|
||||
extern fn LLVMInitializeXCoreTargetInfo() void;
|
||||
extern fn LLVMInitializeAArch64Target() void;
|
||||
extern fn LLVMInitializeAMDGPUTarget() void;
|
||||
extern fn LLVMInitializeARMTarget() void;
|
||||
extern fn LLVMInitializeAVRTarget() void;
|
||||
extern fn LLVMInitializeBPFTarget() void;
|
||||
extern fn LLVMInitializeHexagonTarget() void;
|
||||
extern fn LLVMInitializeLanaiTarget() void;
|
||||
extern fn LLVMInitializeMipsTarget() void;
|
||||
extern fn LLVMInitializeMSP430Target() void;
|
||||
extern fn LLVMInitializeNVPTXTarget() void;
|
||||
extern fn LLVMInitializePowerPCTarget() void;
|
||||
extern fn LLVMInitializeRISCVTarget() void;
|
||||
extern fn LLVMInitializeSparcTarget() void;
|
||||
extern fn LLVMInitializeSystemZTarget() void;
|
||||
extern fn LLVMInitializeWebAssemblyTarget() void;
|
||||
extern fn LLVMInitializeX86Target() void;
|
||||
extern fn LLVMInitializeXCoreTarget() void;
|
||||
extern fn LLVMInitializeAArch64TargetMC() void;
|
||||
extern fn LLVMInitializeAMDGPUTargetMC() void;
|
||||
extern fn LLVMInitializeARMTargetMC() void;
|
||||
extern fn LLVMInitializeAVRTargetMC() void;
|
||||
extern fn LLVMInitializeBPFTargetMC() void;
|
||||
extern fn LLVMInitializeHexagonTargetMC() void;
|
||||
extern fn LLVMInitializeLanaiTargetMC() void;
|
||||
extern fn LLVMInitializeMipsTargetMC() void;
|
||||
extern fn LLVMInitializeMSP430TargetMC() void;
|
||||
extern fn LLVMInitializeNVPTXTargetMC() void;
|
||||
extern fn LLVMInitializePowerPCTargetMC() void;
|
||||
extern fn LLVMInitializeRISCVTargetMC() void;
|
||||
extern fn LLVMInitializeSparcTargetMC() void;
|
||||
extern fn LLVMInitializeSystemZTargetMC() void;
|
||||
extern fn LLVMInitializeWebAssemblyTargetMC() void;
|
||||
extern fn LLVMInitializeX86TargetMC() void;
|
||||
extern fn LLVMInitializeXCoreTargetMC() void;
|
||||
extern fn LLVMInitializeAArch64AsmPrinter() void;
|
||||
extern fn LLVMInitializeAMDGPUAsmPrinter() void;
|
||||
extern fn LLVMInitializeARMAsmPrinter() void;
|
||||
extern fn LLVMInitializeAVRAsmPrinter() void;
|
||||
extern fn LLVMInitializeBPFAsmPrinter() void;
|
||||
extern fn LLVMInitializeHexagonAsmPrinter() void;
|
||||
extern fn LLVMInitializeLanaiAsmPrinter() void;
|
||||
extern fn LLVMInitializeMipsAsmPrinter() void;
|
||||
extern fn LLVMInitializeMSP430AsmPrinter() void;
|
||||
extern fn LLVMInitializeNVPTXAsmPrinter() void;
|
||||
extern fn LLVMInitializePowerPCAsmPrinter() void;
|
||||
extern fn LLVMInitializeRISCVAsmPrinter() void;
|
||||
extern fn LLVMInitializeSparcAsmPrinter() void;
|
||||
extern fn LLVMInitializeSystemZAsmPrinter() void;
|
||||
extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
|
||||
extern fn LLVMInitializeX86AsmPrinter() void;
|
||||
extern fn LLVMInitializeXCoreAsmPrinter() void;
|
||||
extern fn LLVMInitializeAArch64AsmParser() void;
|
||||
extern fn LLVMInitializeAMDGPUAsmParser() void;
|
||||
extern fn LLVMInitializeARMAsmParser() void;
|
||||
extern fn LLVMInitializeAVRAsmParser() void;
|
||||
extern fn LLVMInitializeBPFAsmParser() void;
|
||||
extern fn LLVMInitializeHexagonAsmParser() void;
|
||||
extern fn LLVMInitializeLanaiAsmParser() void;
|
||||
extern fn LLVMInitializeMipsAsmParser() void;
|
||||
extern fn LLVMInitializeMSP430AsmParser() void;
|
||||
extern fn LLVMInitializePowerPCAsmParser() void;
|
||||
extern fn LLVMInitializeRISCVAsmParser() void;
|
||||
extern fn LLVMInitializeSparcAsmParser() void;
|
||||
extern fn LLVMInitializeSystemZAsmParser() void;
|
||||
extern fn LLVMInitializeWebAssemblyAsmParser() void;
|
||||
extern fn LLVMInitializeX86AsmParser() void;
|
||||
pub extern fn LLVMInitializeAArch64TargetInfo() void;
|
||||
pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
||||
pub extern fn LLVMInitializeARMTargetInfo() void;
|
||||
pub extern fn LLVMInitializeAVRTargetInfo() void;
|
||||
pub extern fn LLVMInitializeBPFTargetInfo() void;
|
||||
pub extern fn LLVMInitializeHexagonTargetInfo() void;
|
||||
pub extern fn LLVMInitializeLanaiTargetInfo() void;
|
||||
pub extern fn LLVMInitializeMipsTargetInfo() void;
|
||||
pub extern fn LLVMInitializeMSP430TargetInfo() void;
|
||||
pub extern fn LLVMInitializeNVPTXTargetInfo() void;
|
||||
pub extern fn LLVMInitializePowerPCTargetInfo() void;
|
||||
pub extern fn LLVMInitializeRISCVTargetInfo() void;
|
||||
pub extern fn LLVMInitializeSparcTargetInfo() void;
|
||||
pub extern fn LLVMInitializeSystemZTargetInfo() void;
|
||||
pub extern fn LLVMInitializeWebAssemblyTargetInfo() void;
|
||||
pub extern fn LLVMInitializeX86TargetInfo() void;
|
||||
pub extern fn LLVMInitializeXCoreTargetInfo() void;
|
||||
|
||||
pub const initializeAllTargetInfos = LLVMInitializeAllTargetInfos;
|
||||
fn LLVMInitializeAllTargetInfos() callconv(.C) void {
|
||||
LLVMInitializeAArch64TargetInfo();
|
||||
LLVMInitializeAMDGPUTargetInfo();
|
||||
LLVMInitializeARMTargetInfo();
|
||||
LLVMInitializeAVRTargetInfo();
|
||||
LLVMInitializeBPFTargetInfo();
|
||||
LLVMInitializeHexagonTargetInfo();
|
||||
LLVMInitializeLanaiTargetInfo();
|
||||
LLVMInitializeMipsTargetInfo();
|
||||
LLVMInitializeMSP430TargetInfo();
|
||||
LLVMInitializeNVPTXTargetInfo();
|
||||
LLVMInitializePowerPCTargetInfo();
|
||||
LLVMInitializeRISCVTargetInfo();
|
||||
LLVMInitializeSparcTargetInfo();
|
||||
LLVMInitializeSystemZTargetInfo();
|
||||
LLVMInitializeWebAssemblyTargetInfo();
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeXCoreTargetInfo();
|
||||
}
|
||||
pub const initializeAllTargets = LLVMInitializeAllTargets;
|
||||
fn LLVMInitializeAllTargets() callconv(.C) void {
|
||||
LLVMInitializeAArch64Target();
|
||||
LLVMInitializeAMDGPUTarget();
|
||||
LLVMInitializeARMTarget();
|
||||
LLVMInitializeAVRTarget();
|
||||
LLVMInitializeBPFTarget();
|
||||
LLVMInitializeHexagonTarget();
|
||||
LLVMInitializeLanaiTarget();
|
||||
LLVMInitializeMipsTarget();
|
||||
LLVMInitializeMSP430Target();
|
||||
LLVMInitializeNVPTXTarget();
|
||||
LLVMInitializePowerPCTarget();
|
||||
LLVMInitializeRISCVTarget();
|
||||
LLVMInitializeSparcTarget();
|
||||
LLVMInitializeSystemZTarget();
|
||||
LLVMInitializeWebAssemblyTarget();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeXCoreTarget();
|
||||
}
|
||||
pub const initializeAllTargetMCs = LLVMInitializeAllTargetMCs;
|
||||
fn LLVMInitializeAllTargetMCs() callconv(.C) void {
|
||||
LLVMInitializeAArch64TargetMC();
|
||||
LLVMInitializeAMDGPUTargetMC();
|
||||
LLVMInitializeARMTargetMC();
|
||||
LLVMInitializeAVRTargetMC();
|
||||
LLVMInitializeBPFTargetMC();
|
||||
LLVMInitializeHexagonTargetMC();
|
||||
LLVMInitializeLanaiTargetMC();
|
||||
LLVMInitializeMipsTargetMC();
|
||||
LLVMInitializeMSP430TargetMC();
|
||||
LLVMInitializeNVPTXTargetMC();
|
||||
LLVMInitializePowerPCTargetMC();
|
||||
LLVMInitializeRISCVTargetMC();
|
||||
LLVMInitializeSparcTargetMC();
|
||||
LLVMInitializeSystemZTargetMC();
|
||||
LLVMInitializeWebAssemblyTargetMC();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeXCoreTargetMC();
|
||||
}
|
||||
pub const initializeAllAsmPrinters = LLVMInitializeAllAsmPrinters;
|
||||
fn LLVMInitializeAllAsmPrinters() callconv(.C) void {
|
||||
LLVMInitializeAArch64AsmPrinter();
|
||||
LLVMInitializeAMDGPUAsmPrinter();
|
||||
LLVMInitializeARMAsmPrinter();
|
||||
LLVMInitializeAVRAsmPrinter();
|
||||
LLVMInitializeBPFAsmPrinter();
|
||||
LLVMInitializeHexagonAsmPrinter();
|
||||
LLVMInitializeLanaiAsmPrinter();
|
||||
LLVMInitializeMipsAsmPrinter();
|
||||
LLVMInitializeMSP430AsmPrinter();
|
||||
LLVMInitializeNVPTXAsmPrinter();
|
||||
LLVMInitializePowerPCAsmPrinter();
|
||||
LLVMInitializeRISCVAsmPrinter();
|
||||
LLVMInitializeSparcAsmPrinter();
|
||||
LLVMInitializeSystemZAsmPrinter();
|
||||
LLVMInitializeWebAssemblyAsmPrinter();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeXCoreAsmPrinter();
|
||||
}
|
||||
pub const initializeAllAsmParsers = LLVMInitializeAllAsmParsers;
|
||||
fn LLVMInitializeAllAsmParsers() callconv(.C) void {
|
||||
LLVMInitializeAArch64AsmParser();
|
||||
LLVMInitializeAMDGPUAsmParser();
|
||||
LLVMInitializeARMAsmParser();
|
||||
LLVMInitializeAVRAsmParser();
|
||||
LLVMInitializeBPFAsmParser();
|
||||
LLVMInitializeHexagonAsmParser();
|
||||
LLVMInitializeLanaiAsmParser();
|
||||
LLVMInitializeMipsAsmParser();
|
||||
LLVMInitializeMSP430AsmParser();
|
||||
LLVMInitializePowerPCAsmParser();
|
||||
LLVMInitializeRISCVAsmParser();
|
||||
LLVMInitializeSparcAsmParser();
|
||||
LLVMInitializeSystemZAsmParser();
|
||||
LLVMInitializeWebAssemblyAsmParser();
|
||||
LLVMInitializeX86AsmParser();
|
||||
}
|
||||
pub extern fn LLVMInitializeAArch64Target() void;
|
||||
pub extern fn LLVMInitializeAMDGPUTarget() void;
|
||||
pub extern fn LLVMInitializeARMTarget() void;
|
||||
pub extern fn LLVMInitializeAVRTarget() void;
|
||||
pub extern fn LLVMInitializeBPFTarget() void;
|
||||
pub extern fn LLVMInitializeHexagonTarget() void;
|
||||
pub extern fn LLVMInitializeLanaiTarget() void;
|
||||
pub extern fn LLVMInitializeMipsTarget() void;
|
||||
pub extern fn LLVMInitializeMSP430Target() void;
|
||||
pub extern fn LLVMInitializeNVPTXTarget() void;
|
||||
pub extern fn LLVMInitializePowerPCTarget() void;
|
||||
pub extern fn LLVMInitializeRISCVTarget() void;
|
||||
pub extern fn LLVMInitializeSparcTarget() void;
|
||||
pub extern fn LLVMInitializeSystemZTarget() void;
|
||||
pub extern fn LLVMInitializeWebAssemblyTarget() void;
|
||||
pub extern fn LLVMInitializeX86Target() void;
|
||||
pub extern fn LLVMInitializeXCoreTarget() void;
|
||||
|
||||
pub extern fn LLVMInitializeAArch64TargetMC() void;
|
||||
pub extern fn LLVMInitializeAMDGPUTargetMC() void;
|
||||
pub extern fn LLVMInitializeARMTargetMC() void;
|
||||
pub extern fn LLVMInitializeAVRTargetMC() void;
|
||||
pub extern fn LLVMInitializeBPFTargetMC() void;
|
||||
pub extern fn LLVMInitializeHexagonTargetMC() void;
|
||||
pub extern fn LLVMInitializeLanaiTargetMC() void;
|
||||
pub extern fn LLVMInitializeMipsTargetMC() void;
|
||||
pub extern fn LLVMInitializeMSP430TargetMC() void;
|
||||
pub extern fn LLVMInitializeNVPTXTargetMC() void;
|
||||
pub extern fn LLVMInitializePowerPCTargetMC() void;
|
||||
pub extern fn LLVMInitializeRISCVTargetMC() void;
|
||||
pub extern fn LLVMInitializeSparcTargetMC() void;
|
||||
pub extern fn LLVMInitializeSystemZTargetMC() void;
|
||||
pub extern fn LLVMInitializeWebAssemblyTargetMC() void;
|
||||
pub extern fn LLVMInitializeX86TargetMC() void;
|
||||
pub extern fn LLVMInitializeXCoreTargetMC() void;
|
||||
|
||||
pub extern fn LLVMInitializeAArch64AsmPrinter() void;
|
||||
pub extern fn LLVMInitializeAMDGPUAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeARMAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeAVRAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeBPFAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeHexagonAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeLanaiAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeMipsAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeMSP430AsmPrinter() void;
|
||||
pub extern fn LLVMInitializeNVPTXAsmPrinter() void;
|
||||
pub extern fn LLVMInitializePowerPCAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeRISCVAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeSparcAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeSystemZAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
|
||||
pub extern fn LLVMInitializeX86AsmPrinter() void;
|
||||
pub extern fn LLVMInitializeXCoreAsmPrinter() void;
|
||||
|
||||
pub extern fn LLVMInitializeAArch64AsmParser() void;
|
||||
pub extern fn LLVMInitializeAMDGPUAsmParser() void;
|
||||
pub extern fn LLVMInitializeARMAsmParser() void;
|
||||
pub extern fn LLVMInitializeAVRAsmParser() void;
|
||||
pub extern fn LLVMInitializeBPFAsmParser() void;
|
||||
pub extern fn LLVMInitializeHexagonAsmParser() void;
|
||||
pub extern fn LLVMInitializeLanaiAsmParser() void;
|
||||
pub extern fn LLVMInitializeMipsAsmParser() void;
|
||||
pub extern fn LLVMInitializeMSP430AsmParser() void;
|
||||
pub extern fn LLVMInitializePowerPCAsmParser() void;
|
||||
pub extern fn LLVMInitializeRISCVAsmParser() void;
|
||||
pub extern fn LLVMInitializeSparcAsmParser() void;
|
||||
pub extern fn LLVMInitializeSystemZAsmParser() void;
|
||||
pub extern fn LLVMInitializeWebAssemblyAsmParser() void;
|
||||
pub extern fn LLVMInitializeX86AsmParser() void;
|
||||
|
||||
extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
|
||||
@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{},
|
||||
stub_helper_stubs_start_off: ?u64 = null,
|
||||
|
||||
strtab: std.ArrayListUnmanaged(u8) = .{},
|
||||
strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
|
||||
strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
|
||||
|
||||
got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},
|
||||
got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},
|
||||
@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
|
||||
|
||||
{
|
||||
// Add dyld_stub_binder as the final GOT entry.
|
||||
const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
}) orelse unreachable;
|
||||
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
|
||||
code[9] = 0xff;
|
||||
code[10] = 0x25;
|
||||
{
|
||||
const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
}) orelse unreachable;
|
||||
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
|
||||
code[10] = 0xbf;
|
||||
code[11] = 0xa9;
|
||||
binder_blk_outer: {
|
||||
const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
}) orelse unreachable;
|
||||
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void {
|
||||
}
|
||||
|
||||
// Fourth pass, handle synthetic symbols and flag any undefined references.
|
||||
if (self.strtab_dir.getAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
|
||||
if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
})) |n_strx| blk: {
|
||||
const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
|
||||
@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void {
|
||||
// TODO we should respect the -entry flag passed in by the user to set a custom
|
||||
// entrypoint. For now, assume default of `_main`.
|
||||
const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
|
||||
const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "_main"), StringSliceAdapter{
|
||||
const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
}) orelse {
|
||||
log.err("'_main' export not found", .{});
|
||||
@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
|
||||
const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
|
||||
defer self.base.allocator.free(sym_name);
|
||||
|
||||
if (self.strtab_dir.getAdapted(@as([]const u8, sym_name), StringSliceAdapter{
|
||||
if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
})) |n_strx| {
|
||||
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
|
||||
}
|
||||
|
||||
pub fn makeString(self: *MachO, string: []const u8) !u32 {
|
||||
if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| {
|
||||
const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{
|
||||
.strtab = &self.strtab,
|
||||
}, StringIndexContext{
|
||||
.strtab = &self.strtab,
|
||||
});
|
||||
if (gop.found_existing) {
|
||||
const off = gop.key_ptr.*;
|
||||
log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off });
|
||||
return off;
|
||||
}
|
||||
@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {
|
||||
self.strtab.appendSliceAssumeCapacity(string);
|
||||
self.strtab.appendAssumeCapacity(0);
|
||||
|
||||
try self.strtab_dir.putContext(self.base.allocator, new_off, new_off, StringIndexContext{
|
||||
.strtab = &self.strtab,
|
||||
});
|
||||
gop.key_ptr.* = new_off;
|
||||
|
||||
return new_off;
|
||||
}
|
||||
|
||||
@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
|
||||
parsed_rel.where = .local;
|
||||
parsed_rel.where_index = where_index;
|
||||
} else {
|
||||
const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
|
||||
const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
|
||||
.strtab = &context.macho_file.strtab,
|
||||
}) orelse unreachable;
|
||||
const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
@ -717,7 +717,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
|
||||
const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
|
||||
subtractor = where_index;
|
||||
} else {
|
||||
const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
|
||||
const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
|
||||
.strtab = &context.macho_file.strtab,
|
||||
}) orelse unreachable;
|
||||
const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
|
||||
@ -203,9 +203,7 @@ const Scope = struct {
|
||||
/// Check if the global scope contains this name, without looking into the "future", e.g.
|
||||
/// ignore the preprocessed decl and macro names.
|
||||
fn containsNow(scope: *Root, name: []const u8) bool {
|
||||
return isZigPrimitiveType(name) or
|
||||
scope.sym_table.contains(name) or
|
||||
scope.macro_table.contains(name);
|
||||
return scope.sym_table.contains(name) or scope.macro_table.contains(name);
|
||||
}
|
||||
|
||||
/// Check if the global scope contains the name, includes all decls that haven't been translated yet.
|
||||
@ -495,19 +493,17 @@ fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void {
|
||||
},
|
||||
else => return,
|
||||
} else unreachable;
|
||||
// TODO https://github.com/ziglang/zig/issues/3756
|
||||
// TODO https://github.com/ziglang/zig/issues/1802
|
||||
const name = if (isZigPrimitiveType(decl_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ decl_name, c.getMangle() }) else decl_name;
|
||||
|
||||
const result = try c.unnamed_typedefs.getOrPut(c.gpa, addr);
|
||||
if (result.found_existing) {
|
||||
// One typedef can declare multiple names.
|
||||
// Don't put this one in `decl_table` so it's processed later.
|
||||
return;
|
||||
}
|
||||
result.value_ptr.* = name;
|
||||
result.value_ptr.* = decl_name;
|
||||
// Put this typedef in the decl_table to avoid redefinitions.
|
||||
try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), name);
|
||||
try c.typedefs.put(c.gpa, name, {});
|
||||
try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), decl_name);
|
||||
try c.typedefs.put(c.gpa, decl_name, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -752,10 +748,6 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
const is_pub = mangled_name == null;
|
||||
const is_threadlocal = var_decl.getTLSKind() != .None;
|
||||
const scope = &c.global_scope.base;
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/3756
|
||||
// TODO https://github.com/ziglang/zig/issues/1802
|
||||
const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ var_name, c.getMangle() }) else var_name;
|
||||
const var_decl_loc = var_decl.getLocation();
|
||||
|
||||
const qual_type = var_decl.getTypeSourceInfo_getType();
|
||||
@ -774,7 +766,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
|
||||
const type_node = transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, var_decl_loc) catch |err| switch (err) {
|
||||
error.UnsupportedTranslation, error.UnsupportedType => {
|
||||
return failDecl(c, var_decl_loc, checked_name, "unable to resolve variable type", .{});
|
||||
return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
|
||||
},
|
||||
error.OutOfMemory => |e| return e,
|
||||
};
|
||||
@ -833,11 +825,11 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
.is_threadlocal = is_threadlocal,
|
||||
.linksection_string = linksection_string,
|
||||
.alignment = zigAlignment(var_decl.getAlignedAttribute(c.clang_context)),
|
||||
.name = checked_name,
|
||||
.name = var_name,
|
||||
.type = type_node,
|
||||
.init = init_node,
|
||||
});
|
||||
return addTopLevelDecl(c, checked_name, node);
|
||||
return addTopLevelDecl(c, var_name, node);
|
||||
}
|
||||
|
||||
const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{
|
||||
@ -861,11 +853,7 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa
|
||||
const toplevel = scope.id == .root;
|
||||
const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
|
||||
|
||||
const bare_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin());
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/3756
|
||||
// TODO https://github.com/ziglang/zig/issues/1802
|
||||
var name: []const u8 = if (isZigPrimitiveType(bare_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ bare_name, c.getMangle() }) else bare_name;
|
||||
var name: []const u8 = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin());
|
||||
try c.typedefs.put(c.gpa, name, {});
|
||||
|
||||
if (builtin_typedef_map.get(name)) |builtin| {
|
||||
@ -1535,12 +1523,12 @@ fn transOffsetOfExpr(
|
||||
/// node -> @bitCast(usize, @intCast(isize, node))
|
||||
fn usizeCastForWrappingPtrArithmetic(gpa: *mem.Allocator, node: Node) TransError!Node {
|
||||
const intcast_node = try Tag.int_cast.create(gpa, .{
|
||||
.lhs = try Tag.identifier.create(gpa, "isize"),
|
||||
.lhs = try Tag.type.create(gpa, "isize"),
|
||||
.rhs = node,
|
||||
});
|
||||
|
||||
return Tag.bit_cast.create(gpa, .{
|
||||
.lhs = try Tag.identifier.create(gpa, "usize"),
|
||||
.lhs = try Tag.type.create(gpa, "usize"),
|
||||
.rhs = intcast_node,
|
||||
});
|
||||
}
|
||||
@ -3345,7 +3333,7 @@ fn transSignedArrayAccess(
|
||||
const then_value = try Tag.add.create(c.arena, .{
|
||||
.lhs = container_node,
|
||||
.rhs = try Tag.int_cast.create(c.arena, .{
|
||||
.lhs = try Tag.identifier.create(c.arena, "usize"),
|
||||
.lhs = try Tag.type.create(c.arena, "usize"),
|
||||
.rhs = tmp_ref,
|
||||
}),
|
||||
});
|
||||
@ -3357,7 +3345,7 @@ fn transSignedArrayAccess(
|
||||
|
||||
const minuend = container_node;
|
||||
const signed_size = try Tag.int_cast.create(c.arena, .{
|
||||
.lhs = try Tag.identifier.create(c.arena, "isize"),
|
||||
.lhs = try Tag.type.create(c.arena, "isize"),
|
||||
.rhs = tmp_ref,
|
||||
});
|
||||
const to_cast = try Tag.add_wrap.create(c.arena, .{
|
||||
@ -3365,7 +3353,7 @@ fn transSignedArrayAccess(
|
||||
.rhs = try Tag.negate.create(c.arena, Tag.one_literal.init()),
|
||||
});
|
||||
const bitcast_node = try Tag.bit_cast.create(c.arena, .{
|
||||
.lhs = try Tag.identifier.create(c.arena, "usize"),
|
||||
.lhs = try Tag.type.create(c.arena, "usize"),
|
||||
.rhs = to_cast,
|
||||
});
|
||||
const subtrahend = try Tag.bit_not.create(c.arena, bitcast_node);
|
||||
@ -3421,7 +3409,7 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip
|
||||
const container_node = try transExpr(c, scope, unwrapped_base, .used);
|
||||
const rhs = if (is_longlong or is_signed) blk: {
|
||||
// check if long long first so that signed long long doesn't just become unsigned long long
|
||||
const typeid_node = if (is_longlong) try Tag.identifier.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false);
|
||||
const typeid_node = if (is_longlong) try Tag.type.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false);
|
||||
break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) });
|
||||
} else try transExpr(c, scope, subscr_expr, .used);
|
||||
|
||||
@ -3953,7 +3941,7 @@ fn transFloatingLiteral(c: *Context, scope: *Scope, expr: *const clang.FloatingL
|
||||
|
||||
fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.BinaryConditionalOperator, used: ResultUsed) TransError!Node {
|
||||
// GNU extension of the ternary operator where the middle expression is
|
||||
// omitted, the conditition itself is returned if it evaluates to true
|
||||
// omitted, the condition itself is returned if it evaluates to true
|
||||
const qt = @ptrCast(*const clang.Expr, stmt).getType();
|
||||
const res_is_bool = qualTypeIsBoolean(qt);
|
||||
const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt);
|
||||
@ -4040,7 +4028,7 @@ fn transConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.Condi
|
||||
.then = then_body,
|
||||
.@"else" = else_body,
|
||||
});
|
||||
// Clang inserts ImplicitCast(ToVoid)'s to both rhs and lhs so we don't need to supress the result here.
|
||||
// Clang inserts ImplicitCast(ToVoid)'s to both rhs and lhs so we don't need to suppress the result here.
|
||||
return if_node;
|
||||
}
|
||||
|
||||
@ -4671,6 +4659,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
|
||||
if (@ptrCast(*const clang.Decl, typedef_decl).castToNamedDecl()) |named_decl| {
|
||||
const decl_name = try c.str(named_decl.getName_bytes_begin());
|
||||
if (c.global_names.get(decl_name)) |_| trans_scope = &c.global_scope.base;
|
||||
if (builtin_typedef_map.get(decl_name)) |builtin| return Tag.type.create(c.arena, builtin);
|
||||
}
|
||||
try transTypeDef(c, trans_scope, typedef_decl);
|
||||
const name = c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl())).?;
|
||||
@ -4994,19 +4983,6 @@ pub fn freeErrors(errors: []ClangErrMsg) void {
|
||||
errors.ptr.delete(errors.len);
|
||||
}
|
||||
|
||||
fn isZigPrimitiveType(name: []const u8) bool {
|
||||
if (name.len > 1 and (name[0] == 'u' or name[0] == 'i')) {
|
||||
for (name[1..]) |c| {
|
||||
switch (c) {
|
||||
'0'...'9' => {},
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return @import("AstGen.zig").simple_types.has(name);
|
||||
}
|
||||
|
||||
const PatternList = struct {
|
||||
patterns: []Pattern,
|
||||
|
||||
@ -5311,10 +5287,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
|
||||
const end_loc = clang.Lexer.getLocForEndOfToken(macro.getSourceRange_getEnd(), c.source_manager, unit);
|
||||
|
||||
const name = try c.str(raw_name);
|
||||
// TODO https://github.com/ziglang/zig/issues/3756
|
||||
// TODO https://github.com/ziglang/zig/issues/1802
|
||||
const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ name, c.getMangle() }) else name;
|
||||
if (scope.containsNow(mangled_name)) {
|
||||
if (scope.containsNow(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -5328,7 +5301,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
|
||||
var macro_ctx = MacroCtx{
|
||||
.source = slice,
|
||||
.list = tok_list.items,
|
||||
.name = mangled_name,
|
||||
.name = name,
|
||||
.loc = begin_loc,
|
||||
};
|
||||
assert(mem.eql(u8, macro_ctx.slice(), name));
|
||||
@ -5766,7 +5739,8 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
|
||||
try m.fail(c, "TODO implement function '{s}' in std.zig.c_builtins", .{mangled_name});
|
||||
return error.ParseError;
|
||||
}
|
||||
const identifier = try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
|
||||
if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);
|
||||
const identifier = try Tag.identifier.create(c.arena, mangled_name);
|
||||
scope.skipVariableDiscard(identifier.castTag(.identifier).?.data);
|
||||
return identifier;
|
||||
},
|
||||
@ -6055,7 +6029,8 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_
|
||||
.Identifier => {
|
||||
const mangled_name = scope.getAlias(m.slice());
|
||||
if (!allow_fail or c.typedefs.contains(mangled_name)) {
|
||||
return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
|
||||
if (builtin_typedef_map.get(mangled_name)) |ty| return try Tag.type.create(c.arena, ty);
|
||||
return try Tag.identifier.create(c.arena, mangled_name);
|
||||
}
|
||||
},
|
||||
.Keyword_void => return try Tag.type.create(c.arena, "c_void"),
|
||||
|
||||
@ -801,11 +801,26 @@ const Context = struct {
|
||||
}
|
||||
|
||||
fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
|
||||
return addTokenFmt(c, tag, "{s}", .{bytes});
|
||||
return c.addTokenFmt(tag, "{s}", .{bytes});
|
||||
}
|
||||
|
||||
fn isZigPrimitiveType(name: []const u8) bool {
|
||||
if (name.len > 1 and (name[0] == 'u' or name[0] == 'i')) {
|
||||
for (name[1..]) |c| {
|
||||
switch (c) {
|
||||
'0'...'9' => {},
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return @import("../AstGen.zig").simple_types.has(name);
|
||||
}
|
||||
|
||||
fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
|
||||
return addTokenFmt(c, .identifier, "{s}", .{std.zig.fmtId(bytes)});
|
||||
if (isZigPrimitiveType(bytes))
|
||||
return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes});
|
||||
return c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(bytes)});
|
||||
}
|
||||
|
||||
fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
|
||||
@ -1999,7 +2014,7 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex {
|
||||
members[1] = 0;
|
||||
|
||||
for (payload.fields) |field, i| {
|
||||
const name_tok = try c.addIdentifier(field.name);
|
||||
const name_tok = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field.name)});
|
||||
_ = try c.addToken(.colon, ":");
|
||||
const type_expr = try renderNode(c, field.type);
|
||||
|
||||
@ -2079,7 +2094,7 @@ fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeI
|
||||
.main_token = try c.addToken(.period, "."),
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
.rhs = try c.addIdentifier(field_name),
|
||||
.rhs = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field_name)}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -89,6 +89,8 @@ test {
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
_ = @import("behavior/call.zig");
|
||||
_ = @import("behavior/cast_stage1.zig");
|
||||
// When these tests pass, #9646 can be closed.
|
||||
// _ = @import("behavior/comptime_memory.zig");
|
||||
_ = @import("behavior/const_slice_child.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
|
||||
@ -23,12 +23,12 @@ test "output constraint modifiers" {
|
||||
// This is only testing compilation.
|
||||
var a: u32 = 3;
|
||||
asm volatile (""
|
||||
: [_] "=m,r" (a)
|
||||
: [_] "=m,r" (a),
|
||||
:
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
: [_] "=r,m" (a)
|
||||
: [_] "=r,m" (a),
|
||||
:
|
||||
: ""
|
||||
);
|
||||
@ -38,8 +38,8 @@ test "alternative constraints" {
|
||||
// Make sure we allow commas as a separator for alternative constraints.
|
||||
var a: u32 = 3;
|
||||
asm volatile (""
|
||||
: [_] "=r,m" (a)
|
||||
: [_] "r,m" (a)
|
||||
: [_] "=r,m" (a),
|
||||
: [_] "r,m" (a),
|
||||
: ""
|
||||
);
|
||||
}
|
||||
@ -47,42 +47,42 @@ test "alternative constraints" {
|
||||
test "sized integer/float in asm input" {
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(usize, 3))
|
||||
: [_] "m" (@as(usize, 3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(i15, -3))
|
||||
: [_] "m" (@as(i15, -3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(u3, 3))
|
||||
: [_] "m" (@as(u3, 3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(i3, 3))
|
||||
: [_] "m" (@as(i3, 3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(u121, 3))
|
||||
: [_] "m" (@as(u121, 3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(i121, 3))
|
||||
: [_] "m" (@as(i121, 3)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(f32, 3.17))
|
||||
: [_] "m" (@as(f32, 3.17)),
|
||||
: ""
|
||||
);
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(f64, 3.17))
|
||||
: [_] "m" (@as(f64, 3.17)),
|
||||
: ""
|
||||
);
|
||||
}
|
||||
@ -90,15 +90,15 @@ test "sized integer/float in asm input" {
|
||||
test "struct/array/union types as input values" {
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as([1]u32, undefined))
|
||||
: [_] "m" (@as([1]u32, undefined)),
|
||||
); // fails
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(struct { x: u32, y: u8 }, undefined))
|
||||
: [_] "m" (@as(struct { x: u32, y: u8 }, undefined)),
|
||||
); // fails
|
||||
asm volatile (""
|
||||
:
|
||||
: [_] "m" (@as(union { x: u32, y: u8 }, undefined))
|
||||
: [_] "m" (@as(union { x: u32, y: u8 }, undefined)),
|
||||
); // fails
|
||||
}
|
||||
|
||||
|
||||
317
test/behavior/comptime_memory.zig
Normal file
317
test/behavior/comptime_memory.zig
Normal file
@ -0,0 +1,317 @@
|
||||
const endian = @import("builtin").cpu.arch.endian();
|
||||
const testing = @import("std").testing;
|
||||
const ptr_size = @sizeOf(usize);
|
||||
|
||||
test "type pun signed and unsigned as single pointer" {
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
const y = @ptrCast(*i32, &x);
|
||||
y.* = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x);
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun signed and unsigned as many pointer" {
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
const y = @ptrCast([*]i32, &x);
|
||||
y[0] = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x);
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun signed and unsigned as array pointer" {
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
const y = @ptrCast(*[1]i32, &x);
|
||||
y[0] = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x);
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun signed and unsigned as offset many pointer" {
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
var y = @ptrCast([*]i32, &x);
|
||||
y -= 10;
|
||||
y[10] = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x);
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun signed and unsigned as array pointer" {
|
||||
comptime {
|
||||
var x: u32 = 0;
|
||||
const y = @ptrCast([*]i32, &x) - 10;
|
||||
const z: *[15]i32 = y[0..15];
|
||||
z[10] = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x);
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun value and struct" {
|
||||
comptime {
|
||||
const StructOfU32 = extern struct { x: u32 };
|
||||
var inst: StructOfU32 = .{ .x = 0 };
|
||||
@ptrCast(*i32, &inst.x).* = -1;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFF), inst.x);
|
||||
@ptrCast(*i32, &inst).* = -2;
|
||||
try testing.expectEqual(@as(u32, 0xFFFFFFFE), inst.x);
|
||||
}
|
||||
}
|
||||
|
||||
fn bigToNativeEndian(comptime T: type, v: T) T {
|
||||
return if (endian == .Big) v else @byteSwap(T, v);
|
||||
}
|
||||
test "type pun endianness" {
|
||||
comptime {
|
||||
const StructOfBytes = extern struct { x: [4]u8 };
|
||||
var inst: StructOfBytes = .{ .x = [4]u8{ 0, 0, 0, 0 } };
|
||||
const structPtr = @ptrCast(*align(1) u32, &inst);
|
||||
const arrayPtr = @ptrCast(*align(1) u32, &inst.x);
|
||||
inst.x[0] = 0xFE;
|
||||
inst.x[2] = 0xBE;
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xFE00BE00), structPtr.*);
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xFE00BE00), arrayPtr.*);
|
||||
structPtr.* = bigToNativeEndian(u32, 0xDEADF00D);
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xDEADF00D), structPtr.*);
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xDEADF00D), arrayPtr.*);
|
||||
try testing.expectEqual(@as(u8, 0xDE), inst.x[0]);
|
||||
try testing.expectEqual(@as(u8, 0xAD), inst.x[1]);
|
||||
try testing.expectEqual(@as(u8, 0xF0), inst.x[2]);
|
||||
try testing.expectEqual(@as(u8, 0x0D), inst.x[3]);
|
||||
}
|
||||
}
|
||||
|
||||
const Bits = packed struct {
|
||||
// Note: This struct has only single byte words so it
|
||||
// doesn't need to be byte swapped.
|
||||
p0: u1,
|
||||
p1: u4,
|
||||
p2: u3,
|
||||
p3: u2,
|
||||
p4: u6,
|
||||
p5: u8,
|
||||
p6: u7,
|
||||
p7: u1,
|
||||
};
|
||||
const ShuffledBits = packed struct {
|
||||
p1: u4,
|
||||
p3: u2,
|
||||
p7: u1,
|
||||
p0: u1,
|
||||
p5: u8,
|
||||
p2: u3,
|
||||
p6: u7,
|
||||
p4: u6,
|
||||
};
|
||||
fn shuffle(ptr: usize, comptime From: type, comptime To: type) usize {
|
||||
if (@sizeOf(From) != @sizeOf(To))
|
||||
@compileError("Mismatched sizes! " ++ @typeName(From) ++ " and " ++ @typeName(To) ++ " must have the same size!");
|
||||
const array_len = @divExact(ptr_size, @sizeOf(From));
|
||||
var result: usize = 0;
|
||||
const pSource = @ptrCast(*align(1) const [array_len]From, &ptr);
|
||||
const pResult = @ptrCast(*align(1) [array_len]To, &result);
|
||||
var i: usize = 0;
|
||||
while (i < array_len) : (i += 1) {
|
||||
inline for (@typeInfo(To).Struct.fields) |f| {
|
||||
@field(pResult[i], f.name) = @field(pSource[i], f.name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn doTypePunBitsTest(as_bits: *Bits) !void {
|
||||
const as_u32 = @ptrCast(*align(1) u32, as_bits);
|
||||
const as_bytes = @ptrCast(*[4]u8, as_bits);
|
||||
as_u32.* = bigToNativeEndian(u32, 0xB0A7DEED);
|
||||
try testing.expectEqual(@as(u1, 0x00), as_bits.p0);
|
||||
try testing.expectEqual(@as(u4, 0x08), as_bits.p1);
|
||||
try testing.expectEqual(@as(u3, 0x05), as_bits.p2);
|
||||
try testing.expectEqual(@as(u2, 0x03), as_bits.p3);
|
||||
try testing.expectEqual(@as(u6, 0x29), as_bits.p4);
|
||||
try testing.expectEqual(@as(u8, 0xDE), as_bits.p5);
|
||||
try testing.expectEqual(@as(u7, 0x6D), as_bits.p6);
|
||||
try testing.expectEqual(@as(u1, 0x01), as_bits.p7);
|
||||
|
||||
as_bits.p6 = 0x2D;
|
||||
as_bits.p1 = 0x0F;
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xBEA7DEAD), as_u32.*);
|
||||
|
||||
// clobbering one bit doesn't clobber the word
|
||||
as_bits.p7 = undefined;
|
||||
try testing.expectEqual(@as(u7, 0x2D), as_bits.p6);
|
||||
// even when read as a whole
|
||||
const u = as_u32.*;
|
||||
_ = u; // u is undefined
|
||||
try testing.expectEqual(@as(u7, 0x2D), as_bits.p6);
|
||||
// or if a field which shares the byte is modified
|
||||
as_bits.p6 = 0x6D;
|
||||
try testing.expectEqual(@as(u7, 0x6D), as_bits.p6);
|
||||
|
||||
// but overwriting the undefined will clear it
|
||||
as_bytes[3] = 0xAF;
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0xBEA7DEAF), as_u32.*);
|
||||
}
|
||||
|
||||
test "type pun bits" {
|
||||
comptime {
|
||||
var v: u32 = undefined;
|
||||
try doTypePunBitsTest(@ptrCast(*Bits, &v));
|
||||
}
|
||||
}
|
||||
|
||||
const imports = struct {
|
||||
var global_u32: u32 = 0;
|
||||
};
|
||||
|
||||
// Make sure lazy values work on their own, before getting into more complex tests
|
||||
test "basic pointer preservation" {
|
||||
comptime {
|
||||
const lazy_address = @ptrToInt(&imports.global_u32);
|
||||
try testing.expectEqual(@ptrToInt(&imports.global_u32), lazy_address);
|
||||
try testing.expectEqual(&imports.global_u32, @intToPtr(*u32, lazy_address));
|
||||
}
|
||||
}
|
||||
|
||||
test "byte copy preserves linker value" {
|
||||
const ct_value = comptime blk: {
|
||||
const lazy = &imports.global_u32;
|
||||
var result: *u32 = undefined;
|
||||
const pSource = @ptrCast(*const [ptr_size]u8, &lazy);
|
||||
const pResult = @ptrCast(*[ptr_size]u8, &result);
|
||||
var i: usize = 0;
|
||||
while (i < ptr_size) : (i += 1) {
|
||||
pResult[i] = pSource[i];
|
||||
try testing.expectEqual(pSource[i], pResult[i]);
|
||||
}
|
||||
try testing.expectEqual(&imports.global_u32, result);
|
||||
break :blk result;
|
||||
};
|
||||
|
||||
try testing.expectEqual(&imports.global_u32, ct_value);
|
||||
}
|
||||
|
||||
test "unordered byte copy preserves linker value" {
|
||||
const ct_value = comptime blk: {
|
||||
const lazy = &imports.global_u32;
|
||||
var result: *u32 = undefined;
|
||||
const pSource = @ptrCast(*const [ptr_size]u8, &lazy);
|
||||
const pResult = @ptrCast(*[ptr_size]u8, &result);
|
||||
if (ptr_size > 8) @compileError("This array needs to be expanded for platform with very big pointers");
|
||||
const shuffled_indices = [_]usize{ 4, 5, 2, 6, 1, 3, 0, 7 };
|
||||
for (shuffled_indices) |i| {
|
||||
pResult[i] = pSource[i];
|
||||
try testing.expectEqual(pSource[i], pResult[i]);
|
||||
}
|
||||
try testing.expectEqual(&imports.global_u32, result);
|
||||
break :blk result;
|
||||
};
|
||||
|
||||
try testing.expectEqual(&imports.global_u32, ct_value);
|
||||
}
|
||||
|
||||
test "shuffle chunks of linker value" {
|
||||
const lazy_address = @ptrToInt(&imports.global_u32);
|
||||
const shuffled1_rt = shuffle(lazy_address, Bits, ShuffledBits);
|
||||
const unshuffled1_rt = shuffle(shuffled1_rt, ShuffledBits, Bits);
|
||||
try testing.expectEqual(lazy_address, unshuffled1_rt);
|
||||
const shuffled1_ct = comptime shuffle(lazy_address, Bits, ShuffledBits);
|
||||
const shuffled1_ct_2 = comptime shuffle(lazy_address, Bits, ShuffledBits);
|
||||
comptime try testing.expectEqual(shuffled1_ct, shuffled1_ct_2);
|
||||
const unshuffled1_ct = comptime shuffle(shuffled1_ct, ShuffledBits, Bits);
|
||||
comptime try testing.expectEqual(lazy_address, unshuffled1_ct);
|
||||
try testing.expectEqual(shuffled1_ct, shuffled1_rt);
|
||||
}
|
||||
|
||||
test "dance on linker values" {
|
||||
comptime {
|
||||
var arr: [2]usize = undefined;
|
||||
arr[0] = @ptrToInt(&imports.global_u32);
|
||||
arr[1] = @ptrToInt(&imports.global_u32);
|
||||
|
||||
const weird_ptr = @ptrCast([*]Bits, @ptrCast([*]u8, &arr) + @sizeOf(usize) - 3);
|
||||
try doTypePunBitsTest(&weird_ptr[0]);
|
||||
if (ptr_size > @sizeOf(Bits))
|
||||
try doTypePunBitsTest(&weird_ptr[1]);
|
||||
|
||||
var arr_bytes = @ptrCast(*[2][ptr_size]u8, &arr);
|
||||
|
||||
var rebuilt_bytes: [ptr_size]u8 = undefined;
|
||||
var i: usize = 0;
|
||||
while (i < ptr_size - 3) : (i += 1) {
|
||||
rebuilt_bytes[i] = arr_bytes[0][i];
|
||||
}
|
||||
while (i < ptr_size) : (i += 1) {
|
||||
rebuilt_bytes[i] = arr_bytes[1][i];
|
||||
}
|
||||
|
||||
try testing.expectEqual(&imports.global_u32, @intToPtr(*u32, @bitCast(usize, rebuilt_bytes)));
|
||||
}
|
||||
}
|
||||
|
||||
test "offset array ptr by element size" {
|
||||
comptime {
|
||||
const VirtualStruct = struct { x: u32 };
|
||||
var arr: [4]VirtualStruct = .{
|
||||
.{ .x = bigToNativeEndian(u32, 0x0004080c) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x0105090d) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x02060a0e) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x03070b0f) },
|
||||
};
|
||||
|
||||
const address = @ptrToInt(&arr);
|
||||
try testing.expectEqual(@ptrToInt(&arr[0]), address);
|
||||
try testing.expectEqual(@ptrToInt(&arr[0]) + 10, address + 10);
|
||||
try testing.expectEqual(@ptrToInt(&arr[1]), address + @sizeOf(VirtualStruct));
|
||||
try testing.expectEqual(@ptrToInt(&arr[2]), address + 2 * @sizeOf(VirtualStruct));
|
||||
try testing.expectEqual(@ptrToInt(&arr[3]), address + @sizeOf(VirtualStruct) * 3);
|
||||
|
||||
const secondElement = @intToPtr(*VirtualStruct, @ptrToInt(&arr[0]) + 2 * @sizeOf(VirtualStruct));
|
||||
try testing.expectEqual(bigToNativeEndian(u32, 0x02060a0e), secondElement.x);
|
||||
}
|
||||
}
|
||||
|
||||
test "offset instance by field size" {
|
||||
comptime {
|
||||
const VirtualStruct = struct { x: u32, y: u32, z: u32, w: u32 };
|
||||
var inst = VirtualStruct{ .x = 0, .y = 1, .z = 2, .w = 3 };
|
||||
|
||||
var ptr = @ptrToInt(&inst);
|
||||
ptr -= 4;
|
||||
ptr += @offsetOf(VirtualStruct, "x");
|
||||
try testing.expectEqual(@as(u32, 0), @intToPtr([*]u32, ptr)[1]);
|
||||
ptr -= @offsetOf(VirtualStruct, "x");
|
||||
ptr += @offsetOf(VirtualStruct, "y");
|
||||
try testing.expectEqual(@as(u32, 1), @intToPtr([*]u32, ptr)[1]);
|
||||
ptr = ptr - @offsetOf(VirtualStruct, "y") + @offsetOf(VirtualStruct, "z");
|
||||
try testing.expectEqual(@as(u32, 2), @intToPtr([*]u32, ptr)[1]);
|
||||
ptr = @ptrToInt(&inst.z) - 4 - @offsetOf(VirtualStruct, "z");
|
||||
ptr += @offsetOf(VirtualStruct, "w");
|
||||
try testing.expectEqual(@as(u32, 3), @intToPtr(*u32, ptr + 4).*);
|
||||
}
|
||||
}
|
||||
|
||||
test "offset field ptr by enclosing array element size" {
|
||||
comptime {
|
||||
const VirtualStruct = struct { x: u32 };
|
||||
var arr: [4]VirtualStruct = .{
|
||||
.{ .x = bigToNativeEndian(u32, 0x0004080c) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x0105090d) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x02060a0e) },
|
||||
.{ .x = bigToNativeEndian(u32, 0x03070b0f) },
|
||||
};
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < 4) : (i += 1) {
|
||||
var ptr: [*]u8 = @ptrCast([*]u8, &arr[0]);
|
||||
ptr += i;
|
||||
ptr += @offsetOf(VirtualStruct, "x");
|
||||
var j: usize = 0;
|
||||
while (j < 4) : (j += 1) {
|
||||
const base = ptr + j * @sizeOf(VirtualStruct);
|
||||
try testing.expectEqual(@intCast(u8, i * 4 + j), base[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,8 @@ test "type constructed by comptime function call" {
|
||||
}
|
||||
|
||||
fn SimpleList(comptime L: usize) type {
|
||||
var T = u8;
|
||||
var mutable_T = u8;
|
||||
const T = mutable_T;
|
||||
return struct {
|
||||
array: [L]T,
|
||||
};
|
||||
|
||||
@ -506,7 +506,7 @@ test "lazy typeInfo value as generic parameter" {
|
||||
S.foo(@typeInfo(@TypeOf(.{})));
|
||||
}
|
||||
|
||||
fn A() type {
|
||||
fn ZA() type {
|
||||
return struct {
|
||||
b: B(),
|
||||
|
||||
@ -520,7 +520,7 @@ fn A() type {
|
||||
};
|
||||
}
|
||||
test "non-ambiguous reference of shadowed decls" {
|
||||
try expect(A().B().Self != A().Self);
|
||||
try expect(ZA().B().Self != ZA().Self);
|
||||
}
|
||||
|
||||
test "use of declaration with same name as primitive" {
|
||||
|
||||
@ -984,8 +984,8 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\};
|
||||
, &.{
|
||||
":4:17: error: ambiguous reference",
|
||||
":1:1: note: declared here",
|
||||
":2:5: note: also declared here",
|
||||
":2:5: note: declared here",
|
||||
":1:1: note: also declared here",
|
||||
});
|
||||
|
||||
ctx.compileError("inner func accessing outer var", linux_x64,
|
||||
@ -999,8 +999,9 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\ _ = S;
|
||||
\\}
|
||||
, &.{
|
||||
":5:20: error: 'bar' not accessible from inner function",
|
||||
":2:9: note: declared here",
|
||||
":5:20: error: mutable 'bar' not accessible from here",
|
||||
":2:9: note: declared mutable here",
|
||||
":3:15: note: crosses namespace boundary here",
|
||||
});
|
||||
|
||||
ctx.compileError("global variable redeclaration", linux_x64,
|
||||
|
||||
@ -5342,6 +5342,17 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
"tmp.zig:2:1: note: declared here",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("local shadows global that occurs later",
|
||||
\\pub fn main() void {
|
||||
\\ var foo = true;
|
||||
\\ _ = foo;
|
||||
\\}
|
||||
\\fn foo() void {}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:2:9: error: local shadows declaration of 'foo'",
|
||||
"tmp.zig:5:1: note: declared here",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("switch expression - missing enumeration prong",
|
||||
\\const Number = enum {
|
||||
\\ One,
|
||||
@ -8814,4 +8825,17 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
, &[_][]const u8{
|
||||
"error: Unsupported OS",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("attempt to close over comptime variable from outer scope",
|
||||
\\fn SimpleList(comptime L: usize) type {
|
||||
\\ var T = u8;
|
||||
\\ return struct {
|
||||
\\ array: [L]T,
|
||||
\\ };
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:4:19: error: mutable 'T' not accessible from here",
|
||||
"tmp.zig:2:9: note: declared mutable here",
|
||||
"tmp.zig:3:12: note: crosses namespace boundary here",
|
||||
});
|
||||
}
|
||||
|
||||
@ -160,24 +160,22 @@ const test_targets = blk: {
|
||||
// .link_libc = true,
|
||||
//},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/8155
|
||||
//TestTarget{
|
||||
// .target = .{
|
||||
// .cpu_arch = .mips,
|
||||
// .os_tag = .linux,
|
||||
// .abi = .none,
|
||||
// },
|
||||
//},
|
||||
TestTarget{
|
||||
.target = .{
|
||||
.cpu_arch = .mips,
|
||||
.os_tag = .linux,
|
||||
.abi = .none,
|
||||
},
|
||||
},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/8155
|
||||
//TestTarget{
|
||||
// .target = .{
|
||||
// .cpu_arch = .mips,
|
||||
// .os_tag = .linux,
|
||||
// .abi = .musl,
|
||||
// },
|
||||
// .link_libc = true,
|
||||
//},
|
||||
TestTarget{
|
||||
.target = .{
|
||||
.cpu_arch = .mips,
|
||||
.os_tag = .linux,
|
||||
.abi = .musl,
|
||||
},
|
||||
.link_libc = true,
|
||||
},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/4927
|
||||
//TestTarget{
|
||||
@ -189,24 +187,22 @@ const test_targets = blk: {
|
||||
// .link_libc = true,
|
||||
//},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/8155
|
||||
//TestTarget{
|
||||
// .target = .{
|
||||
// .cpu_arch = .mipsel,
|
||||
// .os_tag = .linux,
|
||||
// .abi = .none,
|
||||
// },
|
||||
//},
|
||||
TestTarget{
|
||||
.target = .{
|
||||
.cpu_arch = .mipsel,
|
||||
.os_tag = .linux,
|
||||
.abi = .none,
|
||||
},
|
||||
},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/8155
|
||||
//TestTarget{
|
||||
// .target = .{
|
||||
// .cpu_arch = .mipsel,
|
||||
// .os_tag = .linux,
|
||||
// .abi = .musl,
|
||||
// },
|
||||
// .link_libc = true,
|
||||
//},
|
||||
TestTarget{
|
||||
.target = .{
|
||||
.cpu_arch = .mipsel,
|
||||
.os_tag = .linux,
|
||||
.abi = .musl,
|
||||
},
|
||||
.link_libc = true,
|
||||
},
|
||||
|
||||
// https://github.com/ziglang/zig/issues/4927
|
||||
//TestTarget{
|
||||
|
||||
@ -318,8 +318,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
\\pub const Color = struct_Color;
|
||||
,
|
||||
\\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
|
||||
\\ return type_1;
|
||||
\\pub inline fn CLITERAL(@"type": anytype) @TypeOf(@"type") {
|
||||
\\ return @"type";
|
||||
\\}
|
||||
,
|
||||
\\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ @as(c_int, 200), @as(c_int, 200), @as(c_int, 200), @as(c_int, 255) });
|
||||
@ -2031,10 +2031,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("shadowing primitive types",
|
||||
\\unsigned anyerror = 2;
|
||||
\\#define noreturn _Noreturn
|
||||
\\typedef enum {
|
||||
\\ f32,
|
||||
\\ u32,
|
||||
\\} BadEnum;
|
||||
, &[_][]const u8{
|
||||
\\pub export var anyerror_1: c_uint = 2;
|
||||
\\pub export var @"anyerror": c_uint = 2;
|
||||
,
|
||||
\\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
|
||||
\\pub const @"noreturn" = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
|
||||
,
|
||||
\\pub const @"f32": c_int = 0;
|
||||
\\pub const @"u32": c_int = 1;
|
||||
\\pub const BadEnum = c_uint;
|
||||
});
|
||||
|
||||
cases.add("floats",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user