x86_64: implement switch jump tables
This commit is contained in:
@@ -161,17 +161,17 @@ const WindowsImpl = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime builtin.mode == .Debug) {
|
||||
if (builtin.mode == .Debug) {
|
||||
// The internal state of the DebugMutex needs to be handled here as well.
|
||||
mutex.impl.locking_thread.store(0, .unordered);
|
||||
}
|
||||
const rc = os.windows.kernel32.SleepConditionVariableSRW(
|
||||
&self.condition,
|
||||
if (comptime builtin.mode == .Debug) &mutex.impl.impl.srwlock else &mutex.impl.srwlock,
|
||||
if (builtin.mode == .Debug) &mutex.impl.impl.srwlock else &mutex.impl.srwlock,
|
||||
timeout_ms,
|
||||
0, // the srwlock was assumed to acquired in exclusive mode not shared
|
||||
);
|
||||
if (comptime builtin.mode == .Debug) {
|
||||
if (builtin.mode == .Debug) {
|
||||
// The internal state of the DebugMutex needs to be handled here as well.
|
||||
mutex.impl.locking_thread.store(std.Thread.getCurrentId(), .unordered);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ const FutexImpl = struct {
|
||||
// On x86, use `lock bts` instead of `lock cmpxchg` as:
|
||||
// - they both seem to mark the cache-line as modified regardless: https://stackoverflow.com/a/63350048
|
||||
// - `lock bts` is smaller instruction-wise which makes it better for inlining
|
||||
if (comptime builtin.target.cpu.arch.isX86()) {
|
||||
if (builtin.target.cpu.arch.isX86()) {
|
||||
const locked_bit = @ctz(locked);
|
||||
return self.state.bitSet(locked_bit, .acquire) == 0;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ pub fn dumpHexFallible(bytes: []const u8) !void {
|
||||
/// TODO multithreaded awareness
|
||||
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
nosuspend {
|
||||
if (comptime builtin.target.isWasm()) {
|
||||
if (builtin.target.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
const stderr = io.getStdErr().writer();
|
||||
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
|
||||
@@ -267,7 +267,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
|
||||
/// TODO multithreaded awareness
|
||||
pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
|
||||
nosuspend {
|
||||
if (comptime builtin.target.isWasm()) {
|
||||
if (builtin.target.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
const stderr = io.getStdErr().writer();
|
||||
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
|
||||
@@ -365,7 +365,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT
|
||||
/// TODO multithreaded awareness
|
||||
pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
|
||||
nosuspend {
|
||||
if (comptime builtin.target.isWasm()) {
|
||||
if (builtin.target.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
const stderr = io.getStdErr().writer();
|
||||
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
|
||||
|
||||
@@ -121,13 +121,13 @@ pub fn deinit(self: *SelfInfo) void {
|
||||
}
|
||||
|
||||
pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module {
|
||||
if (comptime builtin.target.isDarwin()) {
|
||||
if (builtin.target.isDarwin()) {
|
||||
return self.lookupModuleDyld(address);
|
||||
} else if (native_os == .windows) {
|
||||
return self.lookupModuleWin32(address);
|
||||
} else if (native_os == .haiku) {
|
||||
return self.lookupModuleHaiku(address);
|
||||
} else if (comptime builtin.target.isWasm()) {
|
||||
} else if (builtin.target.isWasm()) {
|
||||
return self.lookupModuleWasm(address);
|
||||
} else {
|
||||
return self.lookupModuleDl(address);
|
||||
@@ -138,13 +138,13 @@ pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module {
|
||||
// This can be called when getModuleForAddress fails, so implementations should provide
|
||||
// a path that doesn't rely on any side-effects of a prior successful module lookup.
|
||||
pub fn getModuleNameForAddress(self: *SelfInfo, address: usize) ?[]const u8 {
|
||||
if (comptime builtin.target.isDarwin()) {
|
||||
if (builtin.target.isDarwin()) {
|
||||
return self.lookupModuleNameDyld(address);
|
||||
} else if (native_os == .windows) {
|
||||
return self.lookupModuleNameWin32(address);
|
||||
} else if (native_os == .haiku) {
|
||||
return null;
|
||||
} else if (comptime builtin.target.isWasm()) {
|
||||
} else if (builtin.target.isWasm()) {
|
||||
return null;
|
||||
} else {
|
||||
return self.lookupModuleNameDl(address);
|
||||
|
||||
@@ -890,7 +890,7 @@ test {
|
||||
_ = @import("heap/memory_pool.zig");
|
||||
_ = ArenaAllocator;
|
||||
_ = GeneralPurposeAllocator;
|
||||
if (comptime builtin.target.isWasm()) {
|
||||
if (builtin.target.isWasm()) {
|
||||
_ = WasmAllocator;
|
||||
_ = WasmPageAllocator;
|
||||
}
|
||||
|
||||
@@ -2523,7 +2523,7 @@ pub const Const = struct {
|
||||
/// Returns the number of leading zeros in twos-complement form.
|
||||
pub fn clz(a: Const, bits: Limb) Limb {
|
||||
// Limbs are stored in little-endian order but we need to iterate big-endian.
|
||||
if (!a.positive) return 0;
|
||||
if (!a.positive and !a.eqlZero()) return 0;
|
||||
var total_limb_lz: Limb = 0;
|
||||
var i: usize = a.limbs.len;
|
||||
const bits_per_limb = @bitSizeOf(Limb);
|
||||
|
||||
@@ -157,7 +157,7 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
|
||||
return target;
|
||||
},
|
||||
.freebsd => {
|
||||
if (comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) {
|
||||
if (builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) {
|
||||
var kfile: std.c.kinfo_file = undefined;
|
||||
kfile.structsize = std.c.KINFO_FILE_SIZE;
|
||||
switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) {
|
||||
|
||||
@@ -1061,7 +1061,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
|
||||
// us INVALID_PARAMETER.
|
||||
// The same reasoning for win10_rs5 as in os.renameatW() applies (FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5).
|
||||
var need_fallback = true;
|
||||
if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) {
|
||||
if (builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) {
|
||||
// Deletion with posix semantics if the filesystem supports it.
|
||||
var info = FILE_DISPOSITION_INFORMATION_EX{
|
||||
.Flags = FILE_DISPOSITION_DELETE |
|
||||
|
||||
@@ -6819,7 +6819,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
|
||||
}
|
||||
},
|
||||
.freebsd => {
|
||||
if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt)
|
||||
if (builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt)
|
||||
@compileError("memfd_create is unavailable on FreeBSD < 13.0");
|
||||
const rc = system.memfd_create(name, flags);
|
||||
switch (errno(rc)) {
|
||||
|
||||
@@ -804,7 +804,7 @@ test "getrlimit and setrlimit" {
|
||||
//
|
||||
// This happens for example if RLIMIT_MEMLOCK is bigger than ~2GiB.
|
||||
// In that case the following the limit would be RLIM_INFINITY and the following setrlimit fails with EPERM.
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.link_libc) {
|
||||
if (builtin.cpu.arch.isMIPS() and builtin.link_libc) {
|
||||
if (limit.cur != linux.RLIM.INFINITY) {
|
||||
try posix.setrlimit(resource, limit);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ pub fn interlace(vecs: anytype) @Vector(vectorLength(@TypeOf(vecs[0])) * vecs.le
|
||||
// The indices are correct. The problem seems to be with the @shuffle builtin.
|
||||
// On MIPS, the test that interlaces small_base gives { 0, 2, 0, 0, 64, 255, 248, 200, 0, 0 }.
|
||||
// Calling this with two inputs seems to work fine, but I'll let the compile error trigger for all inputs, just to be safe.
|
||||
comptime if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why interlace() doesn't work on MIPS");
|
||||
if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why interlace() doesn't work on MIPS");
|
||||
|
||||
const VecType = @TypeOf(vecs[0]);
|
||||
const vecs_arr = @as([vecs.len]VecType, vecs);
|
||||
@@ -248,7 +248,7 @@ test "vector patterns" {
|
||||
try std.testing.expectEqual([8]u32{ 10, 20, 30, 40, 55, 66, 77, 88 }, join(base, other_base));
|
||||
try std.testing.expectEqual([2]u32{ 20, 30 }, extract(base, 1, 2));
|
||||
|
||||
if (comptime !builtin.cpu.arch.isMIPS()) {
|
||||
if (!builtin.cpu.arch.isMIPS()) {
|
||||
try std.testing.expectEqual([8]u32{ 10, 55, 20, 66, 30, 77, 40, 88 }, interlace(.{ base, other_base }));
|
||||
|
||||
const small_braid = interlace(small_bases);
|
||||
@@ -390,7 +390,7 @@ pub fn prefixScanWithFunc(
|
||||
comptime identity: std.meta.Child(@TypeOf(vec)),
|
||||
) if (ErrorType == void) @TypeOf(vec) else ErrorType!@TypeOf(vec) {
|
||||
// I haven't debugged this, but it might be a cousin of sorts to what's going on with interlace.
|
||||
comptime if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why prefixScan doesn't work on MIPS");
|
||||
if (builtin.cpu.arch.isMIPS()) @compileError("TODO: Find out why prefixScan doesn't work on MIPS");
|
||||
|
||||
const len = vectorLength(@TypeOf(vec));
|
||||
|
||||
@@ -465,9 +465,7 @@ test "vector prefix scan" {
|
||||
if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060
|
||||
if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893
|
||||
|
||||
if (comptime builtin.cpu.arch.isMIPS()) {
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
|
||||
const int_base = @Vector(4, i32){ 11, 23, 9, -21 };
|
||||
const float_base = @Vector(4, f32){ 2, 0.5, -10, 6.54321 };
|
||||
|
||||
@@ -83,7 +83,7 @@ pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths {
|
||||
|
||||
// TODO: consider also adding homebrew paths
|
||||
// TODO: consider also adding macports paths
|
||||
if (comptime builtin.target.isDarwin()) {
|
||||
if (builtin.target.isDarwin()) {
|
||||
if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: {
|
||||
const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk;
|
||||
try self.addLibDir(try std.fs.path.join(arena, &.{ sdk, "usr/lib" }));
|
||||
|
||||
Reference in New Issue
Block a user