Commit 502eca7b09

Alex Rønne Petersen <alex@alexrp.com>
2025-10-17 01:12:07
std.os.linux: add incomplete mipsn32 arch bits file
This is very likely full of wrong stuff. It's effectively just a copy of the mips64 file - needed because the former stopped using usize/isize. To be clear, this is no more broken than the old situation was; this just makes the brokenness explicit.
1 parent aa8e539
Changed files (2)
lib
lib/std/os/linux/mipsn32.zig
@@ -0,0 +1,271 @@
+// TODO: A lot of this file is very likely wrong.
+
+const builtin = @import("builtin");
+const std = @import("../../std.zig");
+const SYS = std.os.linux.SYS;
+
+pub fn syscall0(number: SYS) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+        : .{ .r1 = true, .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall_pipe(fd: *[2]i32) u32 {
+    return asm volatile (
+        \\ .set noat
+        \\ .set noreorder
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ nop
+        \\ b 2f
+        \\ subu $2, $0, $2
+        \\ 1:
+        \\ sw $2, 0($4)
+        \\ sw $3, 4($4)
+        \\ 2:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(SYS.pipe)),
+          [fd] "{$4}" (fd),
+        : .{ .r1 = true, .r3 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall1(number: SYS, arg1: u32) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ nop
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+        : .{ .r1 = true, .r3 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+        : .{ .r1 = true, .r3 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+          [arg3] "{$6}" (arg3),
+        : .{ .r1 = true, .r3 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+          [arg3] "{$6}" (arg3),
+          [arg4] "{$7}" (arg4),
+        : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+          [arg3] "{$6}" (arg3),
+          [arg4] "{$7}" (arg4),
+          [arg5] "{$8}" (arg5),
+        : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall6(
+    number: SYS,
+    arg1: u32,
+    arg2: u32,
+    arg3: u32,
+    arg4: u32,
+    arg5: u32,
+    arg6: u32,
+) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+          [arg3] "{$6}" (arg3),
+          [arg4] "{$7}" (arg4),
+          [arg5] "{$8}" (arg5),
+          [arg6] "{$9}" (arg6),
+        : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn syscall7(
+    number: SYS,
+    arg1: u32,
+    arg2: u32,
+    arg3: u32,
+    arg4: u32,
+    arg5: u32,
+    arg6: u32,
+    arg7: u32,
+) u32 {
+    return asm volatile (
+        \\ syscall
+        \\ beq $7, $zero, 1f
+        \\ blez $2, 1f
+        \\ dsubu $2, $0, $2
+        \\ 1:
+        : [ret] "={$2}" (-> u32),
+        : [number] "{$2}" (@intFromEnum(number)),
+          [arg1] "{$4}" (arg1),
+          [arg2] "{$5}" (arg2),
+          [arg3] "{$6}" (arg3),
+          [arg4] "{$7}" (arg4),
+          [arg5] "{$8}" (arg5),
+          [arg6] "{$9}" (arg6),
+          [arg7] "{$10}" (arg7),
+        : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
+}
+
+pub fn clone() callconv(.naked) u32 {
+    // __clone(func, stack, flags, arg, ptid, tls, ctid)
+    //         3,    4,     5,     6,   7,    8,   9
+    //
+    // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+    //         2          4,     5,     6,    7,   8
+    asm volatile (
+        \\ # Save function pointer and argument pointer on new thread stack
+        \\ and $5, $5, -16
+        \\ dsubu $5, $5, 16
+        \\ sd $4, 0($5)
+        \\ sd $7, 8($5)
+        \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
+        \\ move $4, $6
+        \\ move $6, $8
+        \\ move $7, $9
+        \\ move $8, $10
+        \\ li $2, 5055 # SYS_clone
+        \\ syscall
+        \\ beq $7, $0, 1f
+        \\ nop
+        \\ jr $ra
+        \\ dsubu $2, $0, $2
+        \\1:
+        \\ beq $2, $0, 1f
+        \\ nop
+        \\ jr $ra
+        \\ nop
+        \\1:
+    );
+    if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
+        \\ .cfi_undefined $ra
+    );
+    asm volatile (
+        \\ move $fp, $zero
+        \\ move $ra, $zero
+        \\
+        \\ ld $25, 0($sp)
+        \\ ld $4, 8($sp)
+        \\ jalr $25
+        \\ nop
+        \\ move $4, $2
+        \\ li $2, 5058 # SYS_exit
+        \\ syscall
+    );
+}
+
+pub const VDSO = struct {
+    pub const CGT_SYM = "__vdso_clock_gettime";
+    pub const CGT_VER = "LINUX_2.6";
+};
+
+pub const blksize_t = u32;
+pub const nlink_t = u32;
+pub const time_t = i32;
+pub const mode_t = u32;
+pub const off_t = i64;
+pub const ino_t = u64;
+pub const dev_t = u64;
+pub const blkcnt_t = i64;
+
+// The `stat` definition used by the Linux kernel.
+pub const Stat = extern struct {
+    dev: dev_t,
+    __pad0: [2]u32, // -1 because our dev_t is u64 (kernel dev_t is really u32).
+    ino: ino_t,
+    mode: mode_t,
+    nlink: nlink_t,
+    uid: std.os.linux.uid_t,
+    gid: std.os.linux.gid_t,
+    rdev: dev_t,
+    __pad1: [2]u32, // -1 because our dev_t is u64 (kernel dev_t is really u32).
+    size: off_t,
+    atim: u32,
+    atim_nsec: u32,
+    mtim: u32,
+    mtim_nsec: u32,
+    ctim: u32,
+    ctim_nsec: u32,
+    blksize: blksize_t,
+    __pad3: u32,
+    blocks: blkcnt_t,
+
+    pub fn atime(self: @This()) std.os.linux.timespec {
+        return .{
+            .sec = self.atim,
+            .nsec = self.atim_nsec,
+        };
+    }
+
+    pub fn mtime(self: @This()) std.os.linux.timespec {
+        return .{
+            .sec = self.mtim,
+            .nsec = self.mtim_nsec,
+        };
+    }
+
+    pub fn ctime(self: @This()) std.os.linux.timespec {
+        return .{
+            .sec = self.ctim,
+            .nsec = self.ctim_nsec,
+        };
+    }
+};
lib/std/os/linux.zig
@@ -43,7 +43,10 @@ const arch_bits = switch (native_arch) {
     .loongarch64 => @import("linux/loongarch64.zig"),
     .m68k => @import("linux/m68k.zig"),
     .mips, .mipsel => @import("linux/mips.zig"),
-    .mips64, .mips64el => @import("linux/mips64.zig"),
+    .mips64, .mips64el => switch (builtin.abi) {
+        .gnuabin32, .muslabin32 => @import("linux/mipsn32.zig"),
+        else => @import("linux/mips64.zig"),
+    },
     .powerpc, .powerpcle => @import("linux/powerpc.zig"),
     .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"),
     .s390x => @import("linux/s390x.zig"),