Merge pull request #8665 from LemonBoy/misc

Miscellaneous patches
This commit is contained in:
Andrew Kelley
2021-05-01 18:07:58 -04:00
committed by GitHub
9 changed files with 306 additions and 49 deletions

View File

@@ -68,11 +68,28 @@ else switch (std.Target.current.os.tag) {
};
/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
pub fn spinLoopHint() void {
pub fn spinLoopHint() callconv(.Inline) void {
switch (std.Target.current.cpu.arch) {
.i386, .x86_64 => asm volatile ("pause" ::: "memory"),
.arm, .aarch64 => asm volatile ("yield" ::: "memory"),
else => {},
.i386, .x86_64 => {
asm volatile ("pause" ::: "memory");
},
.arm, .armeb, .thumb, .thumbeb => {
// `yield` was introduced in v6k but are also available on v6m.
const can_yield = comptime std.Target.arm.featureSetHas(std.Target.current.cpu.features, .has_v6m);
if (can_yield) asm volatile ("yield" ::: "memory");
},
.aarch64, .aarch64_be, .aarch64_32 => {
asm volatile ("isb" ::: "memory");
},
.powerpc64, .powerpc64le => {
// No-op that serves as `yield` hint.
asm volatile ("or 27, 27, 27" ::: "memory");
},
else => {
// Do nothing but prevent the compiler from optimizing away the
// spinning loop.
asm volatile ("" ::: "memory");
},
}
}

View File

@@ -20,6 +20,7 @@ pub fn copysign(comptime T: type, x: T, y: T) T {
f16 => copysign16(x, y),
f32 => copysign32(x, y),
f64 => copysign64(x, y),
f128 => copysign128(x, y),
else => @compileError("copysign not implemented for " ++ @typeName(T)),
};
}
@@ -51,10 +52,20 @@ fn copysign64(x: f64, y: f64) f64 {
return @bitCast(f64, h1 | h2);
}
fn copysign128(x: f128, y: f128) f128 {
const ux = @bitCast(u128, x);
const uy = @bitCast(u128, y);
const h1 = ux & (maxInt(u128) / 2);
const h2 = uy & (@as(u128, 1) << 127);
return @bitCast(f128, h1 | h2);
}
test "math.copysign" {
expect(copysign(f16, 1.0, 1.0) == copysign16(1.0, 1.0));
expect(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0));
expect(copysign(f64, 1.0, 1.0) == copysign64(1.0, 1.0));
expect(copysign(f128, 1.0, 1.0) == copysign128(1.0, 1.0));
}
test "math.copysign16" {
@@ -77,3 +88,10 @@ test "math.copysign64" {
expect(copysign64(-5.0, -1.0) == -5.0);
expect(copysign64(-5.0, 1.0) == 5.0);
}
test "math.copysign128" {
expect(copysign128(5.0, 1.0) == 5.0);
expect(copysign128(5.0, -1.0) == -5.0);
expect(copysign128(-5.0, -1.0) == -5.0);
expect(copysign128(-5.0, 1.0) == 5.0);
}

View File

@@ -24,6 +24,10 @@ pub fn isFinite(x: anytype) bool {
const bits = @bitCast(u64, x);
return bits & (maxInt(u64) >> 1) < (0x7FF << 52);
},
f128 => {
const bits = @bitCast(u128, x);
return bits & (maxInt(u128) >> 1) < (0x7FFF << 112);
},
else => {
@compileError("isFinite not implemented for " ++ @typeName(T));
},
@@ -37,10 +41,24 @@ test "math.isFinite" {
expect(isFinite(@as(f32, -0.0)));
expect(isFinite(@as(f64, 0.0)));
expect(isFinite(@as(f64, -0.0)));
expect(isFinite(@as(f128, 0.0)));
expect(isFinite(@as(f128, -0.0)));
expect(!isFinite(math.inf(f16)));
expect(!isFinite(-math.inf(f16)));
expect(!isFinite(math.inf(f32)));
expect(!isFinite(-math.inf(f32)));
expect(!isFinite(math.inf(f64)));
expect(!isFinite(-math.inf(f64)));
expect(!isFinite(math.inf(f128)));
expect(!isFinite(-math.inf(f128)));
expect(!isFinite(math.nan(f16)));
expect(!isFinite(-math.nan(f16)));
expect(!isFinite(math.nan(f32)));
expect(!isFinite(-math.nan(f32)));
expect(!isFinite(math.nan(f64)));
expect(!isFinite(-math.nan(f64)));
expect(!isFinite(math.nan(f128)));
expect(!isFinite(-math.nan(f128)));
}

View File

@@ -14,6 +14,7 @@ pub fn signbit(x: anytype) bool {
f16 => signbit16(x),
f32 => signbit32(x),
f64 => signbit64(x),
f128 => signbit128(x),
else => @compileError("signbit not implemented for " ++ @typeName(T)),
};
}
@@ -33,10 +34,16 @@ fn signbit64(x: f64) bool {
return bits >> 63 != 0;
}
fn signbit128(x: f128) bool {
const bits = @bitCast(u128, x);
return bits >> 127 != 0;
}
test "math.signbit" {
expect(signbit(@as(f16, 4.0)) == signbit16(4.0));
expect(signbit(@as(f32, 4.0)) == signbit32(4.0));
expect(signbit(@as(f64, 4.0)) == signbit64(4.0));
expect(signbit(@as(f128, 4.0)) == signbit128(4.0));
}
test "math.signbit16" {
@@ -53,3 +60,8 @@ test "math.signbit64" {
expect(!signbit64(4.0));
expect(signbit64(-3.0));
}
test "math.signbit128" {
expect(!signbit128(4.0));
expect(signbit128(-3.0));
}

View File

@@ -10,6 +10,7 @@ usingnamespace @import("../bits.zig");
pub usingnamespace switch (builtin.arch) {
.mips, .mipsel => @import("linux/errno-mips.zig"),
.sparc, .sparcel, .sparcv9 => @import("linux/errno-sparc.zig"),
else => @import("linux/errno-generic.zig"),
};
@@ -247,40 +248,78 @@ else
pub const SIG_SETMASK = 2;
};
pub const SIGHUP = 1;
pub const SIGINT = 2;
pub const SIGQUIT = 3;
pub const SIGILL = 4;
pub const SIGTRAP = 5;
pub const SIGABRT = 6;
pub const SIGIOT = SIGABRT;
pub const SIGBUS = 7;
pub const SIGFPE = 8;
pub const SIGKILL = 9;
pub const SIGUSR1 = 10;
pub const SIGSEGV = 11;
pub const SIGUSR2 = 12;
pub const SIGPIPE = 13;
pub const SIGALRM = 14;
pub const SIGTERM = 15;
pub const SIGSTKFLT = 16;
pub const SIGCHLD = 17;
pub const SIGCONT = 18;
pub const SIGSTOP = 19;
pub const SIGTSTP = 20;
pub const SIGTTIN = 21;
pub const SIGTTOU = 22;
pub const SIGURG = 23;
pub const SIGXCPU = 24;
pub const SIGXFSZ = 25;
pub const SIGVTALRM = 26;
pub const SIGPROF = 27;
pub const SIGWINCH = 28;
pub const SIGIO = 29;
pub const SIGPOLL = 29;
pub const SIGPWR = 30;
pub const SIGSYS = 31;
pub const SIGUNUSED = SIGSYS;
pub usingnamespace if (is_sparc) struct {
pub const SIGHUP = 1;
pub const SIGINT = 2;
pub const SIGQUIT = 3;
pub const SIGILL = 4;
pub const SIGTRAP = 5;
pub const SIGABRT = 6;
pub const SIGEMT = 7;
pub const SIGFPE = 8;
pub const SIGKILL = 9;
pub const SIGBUS = 10;
pub const SIGSEGV = 11;
pub const SIGSYS = 12;
pub const SIGPIPE = 13;
pub const SIGALRM = 14;
pub const SIGTERM = 15;
pub const SIGURG = 16;
pub const SIGSTOP = 17;
pub const SIGTSTP = 18;
pub const SIGCONT = 19;
pub const SIGCHLD = 20;
pub const SIGTTIN = 21;
pub const SIGTTOU = 22;
pub const SIGPOLL = 23;
pub const SIGXCPU = 24;
pub const SIGXFSZ = 25;
pub const SIGVTALRM = 26;
pub const SIGPROF = 27;
pub const SIGWINCH = 28;
pub const SIGLOST = 29;
pub const SIGUSR1 = 30;
pub const SIGUSR2 = 31;
pub const SIGIOT = SIGABRT;
pub const SIGCLD = SIGCHLD;
pub const SIGPWR = SIGLOST;
pub const SIGIO = SIGPOLL;
} else struct {
pub const SIGHUP = 1;
pub const SIGINT = 2;
pub const SIGQUIT = 3;
pub const SIGILL = 4;
pub const SIGTRAP = 5;
pub const SIGABRT = 6;
pub const SIGIOT = SIGABRT;
pub const SIGBUS = 7;
pub const SIGFPE = 8;
pub const SIGKILL = 9;
pub const SIGUSR1 = 10;
pub const SIGSEGV = 11;
pub const SIGUSR2 = 12;
pub const SIGPIPE = 13;
pub const SIGALRM = 14;
pub const SIGTERM = 15;
pub const SIGSTKFLT = 16;
pub const SIGCHLD = 17;
pub const SIGCONT = 18;
pub const SIGSTOP = 19;
pub const SIGTSTP = 20;
pub const SIGTTIN = 21;
pub const SIGTTOU = 22;
pub const SIGURG = 23;
pub const SIGXCPU = 24;
pub const SIGXFSZ = 25;
pub const SIGVTALRM = 26;
pub const SIGPROF = 27;
pub const SIGWINCH = 28;
pub const SIGIO = 29;
pub const SIGPOLL = 29;
pub const SIGPWR = 30;
pub const SIGSYS = 31;
pub const SIGUNUSED = SIGSYS;
};
pub const O_RDONLY = 0o0;
pub const O_WRONLY = 0o1;

View File

@@ -3,6 +3,9 @@
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
// These are MIPS ABI compatible.
pub const EPERM = 1;
pub const ENOENT = 2;
pub const ESRCH = 3;
@@ -37,6 +40,7 @@ pub const EMLINK = 31;
pub const EPIPE = 32;
pub const EDOM = 33;
pub const ERANGE = 34;
pub const ENOMSG = 35;
pub const EIDRM = 36;
pub const ECHRNG = 37;

View File

@@ -0,0 +1,144 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2021 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
// These match the SunOS error numbering scheme.
pub const EPERM = 1;
pub const ENOENT = 2;
pub const ESRCH = 3;
pub const EINTR = 4;
pub const EIO = 5;
pub const ENXIO = 6;
pub const E2BIG = 7;
pub const ENOEXEC = 8;
pub const EBADF = 9;
pub const ECHILD = 10;
pub const EAGAIN = 11;
pub const ENOMEM = 12;
pub const EACCES = 13;
pub const EFAULT = 14;
pub const ENOTBLK = 15;
pub const EBUSY = 16;
pub const EEXIST = 17;
pub const EXDEV = 18;
pub const ENODEV = 19;
pub const ENOTDIR = 20;
pub const EISDIR = 21;
pub const EINVAL = 22;
pub const ENFILE = 23;
pub const EMFILE = 24;
pub const ENOTTY = 25;
pub const ETXTBSY = 26;
pub const EFBIG = 27;
pub const ENOSPC = 28;
pub const ESPIPE = 29;
pub const EROFS = 30;
pub const EMLINK = 31;
pub const EPIPE = 32;
pub const EDOM = 33;
pub const ERANGE = 34;
pub const EWOULDBLOCK = EAGAIN;
pub const EINPROGRESS = 36;
pub const EALREADY = 37;
pub const ENOTSOCK = 38;
pub const EDESTADDRREQ = 39;
pub const EMSGSIZE = 40;
pub const EPROTOTYPE = 41;
pub const ENOPROTOOPT = 42;
pub const EPROTONOSUPPORT = 43;
pub const ESOCKTNOSUPPORT = 44;
pub const EOPNOTSUPP = 45;
pub const EPFNOSUPPORT = 46;
pub const EAFNOSUPPORT = 47;
pub const EADDRINUSE = 48;
pub const EADDRNOTAVAIL = 49;
pub const ENETDOWN = 50;
pub const ENETUNREACH = 51;
pub const ENETRESET = 52;
pub const ECONNABORTED = 53;
pub const ECONNRESET = 54;
pub const ENOBUFS = 55;
pub const EISCONN = 56;
pub const ENOTCONN = 57;
pub const ESHUTDOWN = 58;
pub const ETOOMANYREFS = 59;
pub const ETIMEDOUT = 60;
pub const ECONNREFUSED = 61;
pub const ELOOP = 62;
pub const ENAMETOOLONG = 63;
pub const EHOSTDOWN = 64;
pub const EHOSTUNREACH = 65;
pub const ENOTEMPTY = 66;
pub const EPROCLIM = 67;
pub const EUSERS = 68;
pub const EDQUOT = 69;
pub const ESTALE = 70;
pub const EREMOTE = 71;
pub const ENOSTR = 72;
pub const ETIME = 73;
pub const ENOSR = 74;
pub const ENOMSG = 75;
pub const EBADMSG = 76;
pub const EIDRM = 77;
pub const EDEADLK = 78;
pub const ENOLCK = 79;
pub const ENONET = 80;
pub const ERREMOTE = 81;
pub const ENOLINK = 82;
pub const EADV = 83;
pub const ESRMNT = 84;
pub const ECOMM = 85;
pub const EPROTO = 86;
pub const EMULTIHOP = 87;
pub const EDOTDOT = 88;
pub const EREMCHG = 89;
pub const ENOSYS = 90;
pub const ESTRPIPE = 91;
pub const EOVERFLOW = 92;
pub const EBADFD = 93;
pub const ECHRNG = 94;
pub const EL2NSYNC = 95;
pub const EL3HLT = 96;
pub const EL3RST = 97;
pub const ELNRNG = 98;
pub const EUNATCH = 99;
pub const ENOCSI = 100;
pub const EL2HLT = 101;
pub const EBADE = 102;
pub const EBADR = 103;
pub const EXFULL = 104;
pub const ENOANO = 105;
pub const EBADRQC = 106;
pub const EBADSLT = 107;
pub const EDEADLOCK = 108;
pub const EBFONT = 109;
pub const ELIBEXEC = 110;
pub const ENODATA = 111;
pub const ELIBBAD = 112;
pub const ENOPKG = 113;
pub const ELIBACC = 114;
pub const ENOTUNIQ = 115;
pub const ERESTART = 116;
pub const EUCLEAN = 117;
pub const ENOTNAM = 118;
pub const ENAVAIL = 119;
pub const EISNAM = 120;
pub const EREMOTEIO = 121;
pub const EILSEQ = 122;
pub const ELIBMAX = 123;
pub const ELIBSCN = 124;
pub const ENOMEDIUM = 125;
pub const EMEDIUMTYPE = 126;
pub const ECANCELED = 127;
pub const ENOKEY = 128;
pub const EKEYEXPIRED = 129;
pub const EKEYREVOKED = 130;
pub const EKEYREJECTED = 131;
pub const EOWNERDEAD = 132;
pub const ENOTRECOVERABLE = 133;
pub const ERFKILL = 134;
pub const EHWPOISON = 135;

View File

@@ -386,7 +386,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
}
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
if (@hasField(SYS, "pread64")) {
if (@hasField(SYS, "pread64") and usize_bits < 64) {
const offset_halves = splitValue64(offset);
if (require_aligned_register_pair) {
return syscall6(
@@ -409,8 +409,10 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
);
}
} else {
// Some architectures (eg. 64bit SPARC) pread is called pread64.
const S = if (!@hasField(SYS, "pread") and @hasField(SYS, "pread64")) .pread64 else .pread;
return syscall4(
.pread,
S,
@bitCast(usize, @as(isize, fd)),
@ptrToInt(buf),
count,
@@ -450,7 +452,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
}
pub fn ftruncate(fd: i32, length: u64) usize {
if (@hasField(SYS, "ftruncate64")) {
if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {
const length_halves = splitValue64(length);
if (require_aligned_register_pair) {
return syscall4(
@@ -478,7 +480,7 @@ pub fn ftruncate(fd: i32, length: u64) usize {
}
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
if (@hasField(SYS, "pwrite64")) {
if (@hasField(SYS, "pwrite64") and usize_bits < 64) {
const offset_halves = splitValue64(offset);
if (require_aligned_register_pair) {
@@ -502,8 +504,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
);
}
} else {
// Some architectures (eg. 64bit SPARC) pwrite is called pwrite64.
const S = if (!@hasField(SYS, "pwrite") and @hasField(SYS, "pwrite64")) .pwrite64 else .pwrite;
return syscall4(
.pwrite,
S,
@bitCast(usize, @as(isize, fd)),
@ptrToInt(buf),
count,

View File

@@ -614,23 +614,24 @@ fn clone() callconv(.Naked) void {
\\ # Shuffle the arguments
\\ mov 217, %%g1
\\ mov %%i2, %%o0
\\ sub %%i1, 2047, %%o1
\\ # Add some extra space for the initial frame
\\ sub %%i1, 176 + 2047, %%o1
\\ mov %%i4, %%o2
\\ mov %%i5, %%o3
\\ ldx [%%fp + 192 - 2*8 + 2047], %%o4
\\ ldx [%%fp + 0x8af], %%o4
\\ t 0x6d
\\ bcs,pn %%xcc, 2f
\\ nop
\\ # sparc64 returns the child pid in o0 and a flag telling
\\ # whether the process is the child in o1
\\ # The child pid is returned in o0 while o1 tells if this
\\ # process is # the child (=1) or the parent (=0).
\\ brnz %%o1, 1f
\\ nop
\\ # This is the parent process, return the child pid
\\ # Parent process, return the child pid
\\ mov %%o0, %%i0
\\ ret
\\ restore
\\1:
\\ # This is the child process
\\ # Child process, call func(arg)
\\ mov %%g0, %%fp
\\ call %%g2
\\ mov %%g3, %%o0