authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-05-26 08:09:43+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-05-26 08:11:04+02:00
logecc47695efd1a81e8d713376a54944f5312cd6eb
tree39fdda206d8f615a6f4815836d88ebf8e5d1b7d8
parent0142405f8643d9e464991fb7606b0c5849cf64a1
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.os.linux: add xtensa arch bits

closes https://codeberg.org/ziglang/zig/issues/30947

2 files changed, 203 insertions(+), 0 deletions(-)

lib/std/os/linux.zig+32
...@@ -56,6 +56,7 @@ const arch_bits = switch (native_arch) {...@@ -56,6 +56,7 @@ const arch_bits = switch (native_arch) {
56 .gnux32, .muslx32 => @import("linux/x32.zig"),56 .gnux32, .muslx32 => @import("linux/x32.zig"),
57 else => @import("linux/x86_64.zig"),57 else => @import("linux/x86_64.zig"),
58 },58 },
59 .xtensa, .xtensaeb => @import("linux/xtensa.zig"),
59 else => struct {},60 else => struct {},
60};61};
6162
...@@ -338,6 +339,29 @@ pub const MAP = switch (native_arch) {...@@ -338,6 +339,29 @@ pub const MAP = switch (native_arch) {
338 _20: u1 = 0,339 _20: u1 = 0,
339 _: u5 = 0,340 _: u5 = 0,
340 },341 },
342 .xtensa, .xtensaeb => packed struct(u32) {
343 TYPE: MAP_TYPE,
344 FIXED: bool = false,
345 _RENAME: bool = false,
346 _AUTOGROW: bool = false,
347 _LOCAL: bool = false,
348 _AUTORSRV: bool = false,
349 _1: u1 = 0,
350 NORESERVE: bool = false,
351 ANONYMOUS: bool = false,
352 GROWSDOWN: bool = false,
353 DENYWRITE: bool = false,
354 EXECUTABLE: bool = false,
355 LOCKED: bool = false,
356 POPULATE: bool = false,
357 NONBLOCK: bool = false,
358 STACK: bool = false,
359 HUGETLB: bool = false,
360 FIXED_NOREPLACE: bool = false,
361 _2: u5 = 0,
362 UNINITIALIZED: bool = false,
363 _3: u5 = 0,
364 },
341 else => @compileError("missing std.os.linux.MAP constants for this architecture"),365 else => @compileError("missing std.os.linux.MAP constants for this architecture"),
342};366};
343367
...@@ -497,6 +521,8 @@ pub const O = switch (native_arch) {...@@ -497,6 +521,8 @@ pub const O = switch (native_arch) {
497 .hexagon,521 .hexagon,
498 .or1k,522 .or1k,
499 .s390x,523 .s390x,
524 .xtensa,
525 .xtensaeb,
500 => packed struct(u32) {526 => packed struct(u32) {
501 ACCMODE: ACCMODE = .RDONLY,527 ACCMODE: ACCMODE = .RDONLY,
502 _2: u4 = 0,528 _2: u4 = 0,
...@@ -6617,6 +6643,12 @@ pub const k_sigaction = switch (native_arch) {...@@ -6617,6 +6643,12 @@ pub const k_sigaction = switch (native_arch) {
6617 mask: sigset_t,6643 mask: sigset_t,
6618 flags: c_int,6644 flags: c_int,
6619 },6645 },
6646 .xtensa, .xtensaeb => extern struct {
6647 handler: k_sigaction_funcs.handler,
6648 mask: sigset_t,
6649 flags: c_ulong,
6650 restorer: k_sigaction_funcs.restorer,
6651 },
6620 else => extern struct {6652 else => extern struct {
6621 handler: k_sigaction_funcs.handler,6653 handler: k_sigaction_funcs.handler,
6622 flags: c_ulong,6654 flags: c_ulong,
lib/std/os/linux/xtensa.zig created+171
...@@ -0,0 +1,171 @@
1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u32;
6
7pub fn syscall0(
8 number: SYS,
9) u32 {
10 return asm volatile ("syscall"
11 : [ret] "={a2}" (-> u32),
12 : [number] "{a2}" (@intFromEnum(number)),
13 : .{ .memory = true });
14}
15
16pub fn syscall1(
17 number: SYS,
18 arg1: syscall_arg_t,
19) u32 {
20 return asm volatile ("syscall"
21 : [ret] "={a2}" (-> u32),
22 : [number] "{a2}" (@intFromEnum(number)),
23 [arg1] "{a6}" (arg1),
24 : .{ .memory = true });
25}
26
27pub fn syscall2(
28 number: SYS,
29 arg1: syscall_arg_t,
30 arg2: syscall_arg_t,
31) u32 {
32 return asm volatile ("syscall"
33 : [ret] "={a2}" (-> u32),
34 : [number] "{a2}" (@intFromEnum(number)),
35 [arg1] "{a6}" (arg1),
36 [arg2] "{a3}" (arg2),
37 : .{ .memory = true });
38}
39
40pub fn syscall3(
41 number: SYS,
42 arg1: syscall_arg_t,
43 arg2: syscall_arg_t,
44 arg3: syscall_arg_t,
45) u32 {
46 return asm volatile ("syscall"
47 : [ret] "={a2}" (-> u32),
48 : [number] "{a2}" (@intFromEnum(number)),
49 [arg1] "{a6}" (arg1),
50 [arg2] "{a3}" (arg2),
51 [arg3] "{a4}" (arg3),
52 : .{ .memory = true });
53}
54
55pub fn syscall4(
56 number: SYS,
57 arg1: syscall_arg_t,
58 arg2: syscall_arg_t,
59 arg3: syscall_arg_t,
60 arg4: syscall_arg_t,
61) u32 {
62 return asm volatile ("syscall"
63 : [ret] "={a2}" (-> u32),
64 : [number] "{a2}" (@intFromEnum(number)),
65 [arg1] "{a6}" (arg1),
66 [arg2] "{a3}" (arg2),
67 [arg3] "{a4}" (arg3),
68 [arg4] "{a5}" (arg4),
69 : .{ .memory = true });
70}
71
72pub fn syscall5(
73 number: SYS,
74 arg1: syscall_arg_t,
75 arg2: syscall_arg_t,
76 arg3: syscall_arg_t,
77 arg4: syscall_arg_t,
78 arg5: syscall_arg_t,
79) u32 {
80 return asm volatile ("syscall"
81 : [ret] "={a2}" (-> u32),
82 : [number] "{a2}" (@intFromEnum(number)),
83 [arg1] "{a6}" (arg1),
84 [arg2] "{a3}" (arg2),
85 [arg3] "{a4}" (arg3),
86 [arg4] "{a5}" (arg4),
87 [arg5] "{a8}" (arg5),
88 : .{ .memory = true });
89}
90
91pub fn syscall6(
92 number: SYS,
93 arg1: syscall_arg_t,
94 arg2: syscall_arg_t,
95 arg3: syscall_arg_t,
96 arg4: syscall_arg_t,
97 arg5: syscall_arg_t,
98 arg6: syscall_arg_t,
99) u32 {
100 return asm volatile ("syscall"
101 : [ret] "={a2}" (-> u32),
102 : [number] "{a2}" (@intFromEnum(number)),
103 [arg1] "{a6}" (arg1),
104 [arg2] "{a3}" (arg2),
105 [arg3] "{a4}" (arg3),
106 [arg4] "{a5}" (arg4),
107 [arg5] "{a8}" (arg5),
108 [arg6] "{a9}" (arg6),
109 : .{ .memory = true });
110}
111
112pub fn clone() callconv(.naked) u32 {
113 // __clone(func, stack, flags, arg, ptid, tls, ctid)
114 // a2, a3, a4, a5, a6, a7, +16
115 //
116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117 // a2 a6, a3, a4, a5, a8
118 asm volatile (
119 \\ entry sp, 16
120 \\
121 \\ movi a8, -16
122 \\ and a3, a3, a8
123 \\
124 \\ mov a9, a2
125 \\ mov a10, a5
126 \\
127 \\ mov a5, a7
128 \\ mov a8, a6
129 \\ mov a6, a4
130 \\ mov a4, a8
131 \\ l32i a8, sp, 16
132 \\ movi a2, 116 // SYS_clone
133 \\ syscall
134 \\
135 \\ beqz a2, 1f
136 \\ // parent
137 \\ retw
138 \\
139 \\ // child
140 \\1:
141 \\ movi a7, 0
142 \\ movi a0, 0
143 \\
144 \\ mov a2, a10
145 \\ callx0 a9
146 \\ movi a2, 118 // SYS_exit
147 \\ syscall
148 );
149}
150
151pub const restore = restore_rt;
152
153pub fn restore_rt() callconv(.naked) noreturn {
154 switch (builtin.zig_backend) {
155 .stage2_c => asm volatile (
156 \\ movi a2, %[number]
157 \\ syscall
158 :
159 : [number] "I" (@intFromEnum(SYS.rt_sigreturn)),
160 ),
161 else => asm volatile (
162 \\ syscall
163 :
164 : [number] "{a2}" (@intFromEnum(SYS.rt_sigreturn)),
165 ),
166 }
167}
168
169pub const VDSO = void;
170
171pub const time_t = i32;