diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 5d8ace6606..8d97243826 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1992,8 +1992,8 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag } pub fn fstat(fd: i32, stat_buf: *Stat) usize { - if (native_arch == .riscv32) { - // riscv32 has made the interesting decision to not implement some of + if (native_arch == .riscv32 or native_arch.isLoongArch()) { + // riscv32 and loongarch have made the interesting decision to not implement some of // the older stat syscalls, including this one. @compileError("No fstat syscall on this architecture."); } else if (@hasField(SYS, "fstat64")) { @@ -2004,8 +2004,8 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize { } pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { - if (native_arch == .riscv32) { - // riscv32 has made the interesting decision to not implement some of + if (native_arch == .riscv32 or native_arch.isLoongArch()) { + // riscv32 and loongarch have made the interesting decision to not implement some of // the older stat syscalls, including this one. @compileError("No stat syscall on this architecture."); } else if (@hasField(SYS, "stat64")) { @@ -2016,8 +2016,8 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize { } pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { - if (native_arch == .riscv32) { - // riscv32 has made the interesting decision to not implement some of + if (native_arch == .riscv32 or native_arch.isLoongArch()) { + // riscv32 and loongarch have made the interesting decision to not implement some of // the older stat syscalls, including this one. @compileError("No lstat syscall on this architecture."); } else if (@hasField(SYS, "lstat64")) { @@ -2028,8 +2028,8 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize { } pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize { - if (native_arch == .riscv32) { - // riscv32 has made the interesting decision to not implement some of + if (native_arch == .riscv32 or native_arch.isLoongArch()) { + // riscv32 and loongarch have made the interesting decision to not implement some of // the older stat syscalls, including this one. @compileError("No fstatat syscall on this architecture."); } else if (@hasField(SYS, "fstatat64")) { diff --git a/lib/std/os/linux/loongarch64.zig b/lib/std/os/linux/loongarch64.zig index 160615a966..9ee8fe229c 100644 --- a/lib/std/os/linux/loongarch64.zig +++ b/lib/std/os/linux/loongarch64.zig @@ -2,11 +2,15 @@ const builtin = @import("builtin"); const std = @import("../../std.zig"); const linux = std.os.linux; const SYS = linux.SYS; -const iovec = std.os.iovec; +const iovec = std.posix.iovec; +const iovec_const = std.posix.iovec_const; const uid_t = linux.uid_t; const gid_t = linux.gid_t; const stack_t = linux.stack_t; const sigset_t = linux.sigset_t; +const sockaddr = linux.sockaddr; +const socklen_t = linux.socklen_t; +const timespec = linux.timespec; pub fn syscall0(number: SYS) usize { return asm volatile ( @@ -150,6 +154,30 @@ pub fn restore_rt() callconv(.naked) noreturn { ); } +pub const msghdr = extern struct { + name: ?*sockaddr, + namelen: socklen_t, + iov: [*]iovec, + iovlen: i32, + __pad1: i32 = 0, + control: ?*anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + +pub const msghdr_const = extern struct { + name: ?*const sockaddr, + namelen: socklen_t, + iov: [*]const iovec_const, + iovlen: i32, + __pad1: i32 = 0, + control: ?*const anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + pub const blksize_t = i32; pub const nlink_t = u32; pub const time_t = i64; @@ -159,6 +187,38 @@ pub const ino_t = u64; pub const dev_t = u32; pub const blkcnt_t = i64; +// The `stat` definition used by the Linux kernel. +pub const Stat = extern struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + _pad1: u64, + size: off_t, + blksize: blksize_t, + _pad2: i32, + blocks: blkcnt_t, + atim: timespec, + mtim: timespec, + ctim: timespec, + _pad3: [2]u32, + + pub fn atime(self: @This()) timespec { + return self.atim; + } + + pub fn mtime(self: @This()) timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) timespec { + return self.ctim; + } +}; + pub const timeval = extern struct { tv_sec: time_t, tv_usec: i64, diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index dcde986887..6d2dbe8bc9 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -86,7 +86,7 @@ test "statx" { else => unreachable, } - if (builtin.cpu.arch == .riscv32) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless. + if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless. var stat_buf: linux.Stat = undefined; switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index b26566a99c..677f82b61a 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -283,7 +283,7 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void { test "link with relative paths" { if (native_os == .wasi) return error.SkipZigTest; // Can link, but can't change into tmpDir - if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstat()`. + if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstat()`. if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons. switch (native_os) { @@ -331,7 +331,7 @@ test "link with relative paths" { } test "linkat with different directories" { - if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. + if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons. switch (native_os) { @@ -376,7 +376,7 @@ test "linkat with different directories" { } test "fstatat" { - if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. + if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. // enable when `fstat` and `fstatat` are implemented on Windows if (native_os == .windows) return error.SkipZigTest; @@ -1265,7 +1265,7 @@ test "fchmodat smoke test" { ); posix.close(fd); - if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. + if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`. try posix.symlinkat("regfile", tmp.dir.fd, "symlink"); const sym_mode = blk: { diff --git a/test/behavior/prefetch.zig b/test/behavior/prefetch.zig index e98e848393..f5ae5550d3 100644 --- a/test/behavior/prefetch.zig +++ b/test/behavior/prefetch.zig @@ -3,6 +3,7 @@ const std = @import("std"); test "@prefetch()" { if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/134624 var a: [2]u32 = .{ 42, 42 }; var a_len = a.len; diff --git a/test/tests.zig b/test/tests.zig index 0944c2a77d..43a631512d 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -497,6 +497,33 @@ const test_targets = blk: { .pic = false, // Long calls don't work with PIC. }, + .{ + .target = .{ + .cpu_arch = .loongarch64, + .os_tag = .linux, + .abi = .none, + }, + .skip_modules = &.{"std"}, + }, + .{ + .target = .{ + .cpu_arch = .loongarch64, + .os_tag = .linux, + .abi = .musl, + }, + .link_libc = true, + .skip_modules = &.{"std"}, + }, + .{ + .target = .{ + .cpu_arch = .loongarch64, + .os_tag = .linux, + .abi = .gnu, + }, + .link_libc = true, + .skip_modules = &.{"std"}, + }, + .{ .target = .{ .cpu_arch = .mips,