From ecc47695efd1a81e8d713376a54944f5312cd6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 26 May 2026 08:09:43 +0200 Subject: [PATCH] std.os.linux: add xtensa arch bits closes https://codeberg.org/ziglang/zig/issues/30947 --- lib/std/os/linux.zig | 32 +++++++ lib/std/os/linux/xtensa.zig | 171 ++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 lib/std/os/linux/xtensa.zig diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 8f9e7c178307bff79c98356155549c8bbd9ff360..33b4f640591c6591b276d9cbf5c7e443b586e957 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -56,6 +56,7 @@ const arch_bits = switch (native_arch) { .gnux32, .muslx32 => @import("linux/x32.zig"), else => @import("linux/x86_64.zig"), }, + .xtensa, .xtensaeb => @import("linux/xtensa.zig"), else => struct {}, }; @@ -338,6 +339,29 @@ pub const MAP = switch (native_arch) { _20: u1 = 0, _: u5 = 0, }, + .xtensa, .xtensaeb => packed struct(u32) { + TYPE: MAP_TYPE, + FIXED: bool = false, + _RENAME: bool = false, + _AUTOGROW: bool = false, + _LOCAL: bool = false, + _AUTORSRV: bool = false, + _1: u1 = 0, + NORESERVE: bool = false, + ANONYMOUS: bool = false, + GROWSDOWN: bool = false, + DENYWRITE: bool = false, + EXECUTABLE: bool = false, + LOCKED: bool = false, + POPULATE: bool = false, + NONBLOCK: bool = false, + STACK: bool = false, + HUGETLB: bool = false, + FIXED_NOREPLACE: bool = false, + _2: u5 = 0, + UNINITIALIZED: bool = false, + _3: u5 = 0, + }, else => @compileError("missing std.os.linux.MAP constants for this architecture"), }; @@ -497,6 +521,8 @@ pub const O = switch (native_arch) { .hexagon, .or1k, .s390x, + .xtensa, + .xtensaeb, => packed struct(u32) { ACCMODE: ACCMODE = .RDONLY, _2: u4 = 0, @@ -6617,6 +6643,12 @@ pub const k_sigaction = switch (native_arch) { mask: sigset_t, flags: c_int, }, + .xtensa, .xtensaeb => extern struct { + handler: k_sigaction_funcs.handler, + mask: sigset_t, + flags: c_ulong, + restorer: k_sigaction_funcs.restorer, + }, else => extern struct { handler: k_sigaction_funcs.handler, flags: c_ulong, diff --git a/lib/std/os/linux/xtensa.zig b/lib/std/os/linux/xtensa.zig new file mode 100644 index 0000000000000000000000000000000000000000..7a4c065c7328fc48fdd64e512e5471f7a3dbf7e8 --- /dev/null +++ b/lib/std/os/linux/xtensa.zig @@ -0,0 +1,171 @@ +const builtin = @import("builtin"); +const std = @import("../../std.zig"); +const SYS = std.os.linux.SYS; + +pub const syscall_arg_t = u32; + +pub fn syscall0( + number: SYS, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + : .{ .memory = true }); +} + +pub fn syscall1( + number: SYS, + arg1: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + : .{ .memory = true }); +} + +pub fn syscall2( + number: SYS, + arg1: syscall_arg_t, + arg2: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + [arg2] "{a3}" (arg2), + : .{ .memory = true }); +} + +pub fn syscall3( + number: SYS, + arg1: syscall_arg_t, + arg2: syscall_arg_t, + arg3: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + [arg2] "{a3}" (arg2), + [arg3] "{a4}" (arg3), + : .{ .memory = true }); +} + +pub fn syscall4( + number: SYS, + arg1: syscall_arg_t, + arg2: syscall_arg_t, + arg3: syscall_arg_t, + arg4: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + [arg2] "{a3}" (arg2), + [arg3] "{a4}" (arg3), + [arg4] "{a5}" (arg4), + : .{ .memory = true }); +} + +pub fn syscall5( + number: SYS, + arg1: syscall_arg_t, + arg2: syscall_arg_t, + arg3: syscall_arg_t, + arg4: syscall_arg_t, + arg5: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + [arg2] "{a3}" (arg2), + [arg3] "{a4}" (arg3), + [arg4] "{a5}" (arg4), + [arg5] "{a8}" (arg5), + : .{ .memory = true }); +} + +pub fn syscall6( + number: SYS, + arg1: syscall_arg_t, + arg2: syscall_arg_t, + arg3: syscall_arg_t, + arg4: syscall_arg_t, + arg5: syscall_arg_t, + arg6: syscall_arg_t, +) u32 { + return asm volatile ("syscall" + : [ret] "={a2}" (-> u32), + : [number] "{a2}" (@intFromEnum(number)), + [arg1] "{a6}" (arg1), + [arg2] "{a3}" (arg2), + [arg3] "{a4}" (arg3), + [arg4] "{a5}" (arg4), + [arg5] "{a8}" (arg5), + [arg6] "{a9}" (arg6), + : .{ .memory = true }); +} + +pub fn clone() callconv(.naked) u32 { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // a2, a3, a4, a5, a6, a7, +16 + // + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // a2 a6, a3, a4, a5, a8 + asm volatile ( + \\ entry sp, 16 + \\ + \\ movi a8, -16 + \\ and a3, a3, a8 + \\ + \\ mov a9, a2 + \\ mov a10, a5 + \\ + \\ mov a5, a7 + \\ mov a8, a6 + \\ mov a6, a4 + \\ mov a4, a8 + \\ l32i a8, sp, 16 + \\ movi a2, 116 // SYS_clone + \\ syscall + \\ + \\ beqz a2, 1f + \\ // parent + \\ retw + \\ + \\ // child + \\1: + \\ movi a7, 0 + \\ movi a0, 0 + \\ + \\ mov a2, a10 + \\ callx0 a9 + \\ movi a2, 118 // SYS_exit + \\ syscall + ); +} + +pub const restore = restore_rt; + +pub fn restore_rt() callconv(.naked) noreturn { + switch (builtin.zig_backend) { + .stage2_c => asm volatile ( + \\ movi a2, %[number] + \\ syscall + : + : [number] "I" (@intFromEnum(SYS.rt_sigreturn)), + ), + else => asm volatile ( + \\ syscall + : + : [number] "{a2}" (@intFromEnum(SYS.rt_sigreturn)), + ), + } +} + +pub const VDSO = void; + +pub const time_t = i32; -- 2.54.0