authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-08 01:02:24+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-04-08 01:02:24+02:00
logd8153fa74ab01f8cdc117e0049e0a2d2e4187892
tree6df1488df5ba7367d620c1bbf4c414c3912c69bc
parentfb1d4990cb60e805236122256da99d80c50ee0d4
parentf8439805d7d9ab64f34e97272ac13bdd21c7401e
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #23495 from alexrp/loongarch

Some `loongarch64-linux` porting work

6 files changed, 102 insertions(+), 14 deletions(-)

lib/std/os/linux.zig+8-8
...@@ -1992,8 +1992,8 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag...@@ -1992,8 +1992,8 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag
1992}1992}
19931993
1994pub fn fstat(fd: i32, stat_buf: *Stat) usize {1994pub fn fstat(fd: i32, stat_buf: *Stat) usize {
1995 if (native_arch == .riscv32) {1995 if (native_arch == .riscv32 or native_arch.isLoongArch()) {
1996 // riscv32 has made the interesting decision to not implement some of1996 // riscv32 and loongarch have made the interesting decision to not implement some of
1997 // the older stat syscalls, including this one.1997 // the older stat syscalls, including this one.
1998 @compileError("No fstat syscall on this architecture.");1998 @compileError("No fstat syscall on this architecture.");
1999 } else if (@hasField(SYS, "fstat64")) {1999 } else if (@hasField(SYS, "fstat64")) {
...@@ -2004,8 +2004,8 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {...@@ -2004,8 +2004,8 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {
2004}2004}
20052005
2006pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {2006pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {
2007 if (native_arch == .riscv32) {2007 if (native_arch == .riscv32 or native_arch.isLoongArch()) {
2008 // riscv32 has made the interesting decision to not implement some of2008 // riscv32 and loongarch have made the interesting decision to not implement some of
2009 // the older stat syscalls, including this one.2009 // the older stat syscalls, including this one.
2010 @compileError("No stat syscall on this architecture.");2010 @compileError("No stat syscall on this architecture.");
2011 } else if (@hasField(SYS, "stat64")) {2011 } else if (@hasField(SYS, "stat64")) {
...@@ -2016,8 +2016,8 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {...@@ -2016,8 +2016,8 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {
2016}2016}
20172017
2018pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {2018pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
2019 if (native_arch == .riscv32) {2019 if (native_arch == .riscv32 or native_arch.isLoongArch()) {
2020 // riscv32 has made the interesting decision to not implement some of2020 // riscv32 and loongarch have made the interesting decision to not implement some of
2021 // the older stat syscalls, including this one.2021 // the older stat syscalls, including this one.
2022 @compileError("No lstat syscall on this architecture.");2022 @compileError("No lstat syscall on this architecture.");
2023 } else if (@hasField(SYS, "lstat64")) {2023 } else if (@hasField(SYS, "lstat64")) {
...@@ -2028,8 +2028,8 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {...@@ -2028,8 +2028,8 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
2028}2028}
20292029
2030pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize {2030pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize {
2031 if (native_arch == .riscv32) {2031 if (native_arch == .riscv32 or native_arch.isLoongArch()) {
2032 // riscv32 has made the interesting decision to not implement some of2032 // riscv32 and loongarch have made the interesting decision to not implement some of
2033 // the older stat syscalls, including this one.2033 // the older stat syscalls, including this one.
2034 @compileError("No fstatat syscall on this architecture.");2034 @compileError("No fstatat syscall on this architecture.");
2035 } else if (@hasField(SYS, "fstatat64")) {2035 } else if (@hasField(SYS, "fstatat64")) {
lib/std/os/linux/loongarch64.zig+61-1
...@@ -2,11 +2,15 @@ const builtin = @import("builtin");...@@ -2,11 +2,15 @@ const builtin = @import("builtin");
2const std = @import("../../std.zig");2const std = @import("../../std.zig");
3const linux = std.os.linux;3const linux = std.os.linux;
4const SYS = linux.SYS;4const SYS = linux.SYS;
5const iovec = std.os.iovec;5const iovec = std.posix.iovec;
6const iovec_const = std.posix.iovec_const;
6const uid_t = linux.uid_t;7const uid_t = linux.uid_t;
7const gid_t = linux.gid_t;8const gid_t = linux.gid_t;
8const stack_t = linux.stack_t;9const stack_t = linux.stack_t;
9const sigset_t = linux.sigset_t;10const sigset_t = linux.sigset_t;
11const sockaddr = linux.sockaddr;
12const socklen_t = linux.socklen_t;
13const timespec = linux.timespec;
1014
11pub fn syscall0(number: SYS) usize {15pub fn syscall0(number: SYS) usize {
12 return asm volatile (16 return asm volatile (
...@@ -150,6 +154,30 @@ pub fn restore_rt() callconv(.naked) noreturn {...@@ -150,6 +154,30 @@ pub fn restore_rt() callconv(.naked) noreturn {
150 );154 );
151}155}
152156
157pub const msghdr = extern struct {
158 name: ?*sockaddr,
159 namelen: socklen_t,
160 iov: [*]iovec,
161 iovlen: i32,
162 __pad1: i32 = 0,
163 control: ?*anyopaque,
164 controllen: socklen_t,
165 __pad2: socklen_t = 0,
166 flags: i32,
167};
168
169pub const msghdr_const = extern struct {
170 name: ?*const sockaddr,
171 namelen: socklen_t,
172 iov: [*]const iovec_const,
173 iovlen: i32,
174 __pad1: i32 = 0,
175 control: ?*const anyopaque,
176 controllen: socklen_t,
177 __pad2: socklen_t = 0,
178 flags: i32,
179};
180
153pub const blksize_t = i32;181pub const blksize_t = i32;
154pub const nlink_t = u32;182pub const nlink_t = u32;
155pub const time_t = i64;183pub const time_t = i64;
...@@ -159,6 +187,38 @@ pub const ino_t = u64;...@@ -159,6 +187,38 @@ pub const ino_t = u64;
159pub const dev_t = u32;187pub const dev_t = u32;
160pub const blkcnt_t = i64;188pub const blkcnt_t = i64;
161189
190// The `stat` definition used by the Linux kernel.
191pub const Stat = extern struct {
192 dev: dev_t,
193 ino: ino_t,
194 mode: mode_t,
195 nlink: nlink_t,
196 uid: uid_t,
197 gid: gid_t,
198 rdev: dev_t,
199 _pad1: u64,
200 size: off_t,
201 blksize: blksize_t,
202 _pad2: i32,
203 blocks: blkcnt_t,
204 atim: timespec,
205 mtim: timespec,
206 ctim: timespec,
207 _pad3: [2]u32,
208
209 pub fn atime(self: @This()) timespec {
210 return self.atim;
211 }
212
213 pub fn mtime(self: @This()) timespec {
214 return self.mtim;
215 }
216
217 pub fn ctime(self: @This()) timespec {
218 return self.ctim;
219 }
220};
221
162pub const timeval = extern struct {222pub const timeval = extern struct {
163 tv_sec: time_t,223 tv_sec: time_t,
164 tv_usec: i64,224 tv_usec: i64,
lib/std/os/linux/test.zig+1-1
...@@ -86,7 +86,7 @@ test "statx" {...@@ -86,7 +86,7 @@ test "statx" {
86 else => unreachable,86 else => unreachable,
87 }87 }
8888
89 if (builtin.cpu.arch == .riscv32) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.89 if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.
9090
91 var stat_buf: linux.Stat = undefined;91 var stat_buf: linux.Stat = undefined;
92 switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {92 switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
lib/std/posix/test.zig+4-4
...@@ -283,7 +283,7 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {...@@ -283,7 +283,7 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
283283
284test "link with relative paths" {284test "link with relative paths" {
285 if (native_os == .wasi) return error.SkipZigTest; // Can link, but can't change into tmpDir285 if (native_os == .wasi) return error.SkipZigTest; // Can link, but can't change into tmpDir
286 if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstat()`.286 if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstat()`.
287 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.287 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.
288288
289 switch (native_os) {289 switch (native_os) {
...@@ -331,7 +331,7 @@ test "link with relative paths" {...@@ -331,7 +331,7 @@ test "link with relative paths" {
331}331}
332332
333test "linkat with different directories" {333test "linkat with different directories" {
334 if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.334 if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
335 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.335 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.
336336
337 switch (native_os) {337 switch (native_os) {
...@@ -376,7 +376,7 @@ test "linkat with different directories" {...@@ -376,7 +376,7 @@ test "linkat with different directories" {
376}376}
377377
378test "fstatat" {378test "fstatat" {
379 if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.379 if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
380 // enable when `fstat` and `fstatat` are implemented on Windows380 // enable when `fstat` and `fstatat` are implemented on Windows
381 if (native_os == .windows) return error.SkipZigTest;381 if (native_os == .windows) return error.SkipZigTest;
382382
...@@ -1265,7 +1265,7 @@ test "fchmodat smoke test" {...@@ -1265,7 +1265,7 @@ test "fchmodat smoke test" {
1265 );1265 );
1266 posix.close(fd);1266 posix.close(fd);
12671267
1268 if (builtin.cpu.arch == .riscv32 and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.1268 if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
12691269
1270 try posix.symlinkat("regfile", tmp.dir.fd, "symlink");1270 try posix.symlinkat("regfile", tmp.dir.fd, "symlink");
1271 const sym_mode = blk: {1271 const sym_mode = blk: {
test/behavior/prefetch.zig+1
...@@ -3,6 +3,7 @@ const std = @import("std");...@@ -3,6 +3,7 @@ const std = @import("std");
33
4test "@prefetch()" {4test "@prefetch()" {
5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/134624
67
7 var a: [2]u32 = .{ 42, 42 };8 var a: [2]u32 = .{ 42, 42 };
8 var a_len = a.len;9 var a_len = a.len;
test/tests.zig+27
...@@ -497,6 +497,33 @@ const test_targets = blk: {...@@ -497,6 +497,33 @@ const test_targets = blk: {
497 .pic = false, // Long calls don't work with PIC.497 .pic = false, // Long calls don't work with PIC.
498 },498 },
499499
500 .{
501 .target = .{
502 .cpu_arch = .loongarch64,
503 .os_tag = .linux,
504 .abi = .none,
505 },
506 .skip_modules = &.{"std"},
507 },
508 .{
509 .target = .{
510 .cpu_arch = .loongarch64,
511 .os_tag = .linux,
512 .abi = .musl,
513 },
514 .link_libc = true,
515 .skip_modules = &.{"std"},
516 },
517 .{
518 .target = .{
519 .cpu_arch = .loongarch64,
520 .os_tag = .linux,
521 .abi = .gnu,
522 },
523 .link_libc = true,
524 .skip_modules = &.{"std"},
525 },
526
500 .{527 .{
501 .target = .{528 .target = .{
502 .cpu_arch = .mips,529 .cpu_arch = .mips,