authorgravatar for contact@taylor.fishtaylor.fish <contact@taylor.fish> 2025-09-13 17:17:18-07:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-09-24 03:50:34+02:00
log427f0025dbea242b4cd760e7569eb625da5c0910
treee04df9f69910cefa826cc8ce32b614061df313f5
parent1f0cf7c5514587471a219c418c15b49413d0fd14
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Fix PowerPC syscalls causing invalid code from CBE

Fixes #25209. On PowerPC, some registers are both inputs to syscalls and clobbered by them. An example is r0, which initially contains the syscall number, but may be overwritten during execution of the syscall. musl and glibc use a `+` (read-write) constraint to indicate this, which isn't supported in Zig. The current implementation of PowerPC syscalls in the Zig standard library instead lists these registers as both inputs and clobbers, but this results in the C backend generating code that is invalid for at least some C compilers, like GCC, which doesn't support the specifying the same register as both an input and a clobber. This PR changes the PowerPC syscall functions to list such registers as inputs and outputs rather than inputs and clobbers. Thanks to jacobly0 who pointed out that it's possible to have multiple outputs; I had gotten the wrong idea from the documentation.

2 files changed, 122 insertions(+), 14 deletions(-)

lib/std/os/linux/powerpc.zig+61-7
...@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;...@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;
15const timespec = linux.timespec;15const timespec = linux.timespec;
1616
17pub fn syscall0(number: SYS) usize {17pub fn syscall0(number: SYS) usize {
18 // r0 is both an input register and a clobber. musl and glibc achieve this with
19 // a "+" constraint, which isn't supported in Zig, so instead we separately list
20 // r0 as both an input and an output. (Listing it as an input and a clobber would
21 // cause the C backend to emit invalid code; see #25209.)
22 var r0_out: usize = undefined;
18 return asm volatile (23 return asm volatile (
19 \\ sc24 \\ sc
20 \\ bns+ 1f25 \\ bns+ 1f
21 \\ neg 3, 326 \\ neg 3, 3
22 \\ 1:27 \\ 1:
23 : [ret] "={r3}" (-> usize),28 : [ret] "={r3}" (-> usize),
29 [r0_out] "={r0}" (r0_out),
24 : [number] "{r0}" (@intFromEnum(number)),30 : [number] "{r0}" (@intFromEnum(number)),
25 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });31 : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
26}32}
2733
28pub fn syscall1(number: SYS, arg1: usize) usize {34pub fn syscall1(number: SYS, arg1: usize) usize {
35 // r0 is both an input and a clobber.
36 var r0_out: usize = undefined;
29 return asm volatile (37 return asm volatile (
30 \\ sc38 \\ sc
31 \\ bns+ 1f39 \\ bns+ 1f
32 \\ neg 3, 340 \\ neg 3, 3
33 \\ 1:41 \\ 1:
34 : [ret] "={r3}" (-> usize),42 : [ret] "={r3}" (-> usize),
43 [r0_out] "={r0}" (r0_out),
35 : [number] "{r0}" (@intFromEnum(number)),44 : [number] "{r0}" (@intFromEnum(number)),
36 [arg1] "{r3}" (arg1),45 [arg1] "{r3}" (arg1),
37 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });46 : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
38}47}
3948
40pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {49pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
50 // These registers are both inputs and clobbers.
51 var r0_out: usize = undefined;
52 var r4_out: usize = undefined;
41 return asm volatile (53 return asm volatile (
42 \\ sc54 \\ sc
43 \\ bns+ 1f55 \\ bns+ 1f
44 \\ neg 3, 356 \\ neg 3, 3
45 \\ 1:57 \\ 1:
46 : [ret] "={r3}" (-> usize),58 : [ret] "={r3}" (-> usize),
59 [r0_out] "={r0}" (r0_out),
60 [r4_out] "={r4}" (r4_out),
47 : [number] "{r0}" (@intFromEnum(number)),61 : [number] "{r0}" (@intFromEnum(number)),
48 [arg1] "{r3}" (arg1),62 [arg1] "{r3}" (arg1),
49 [arg2] "{r4}" (arg2),63 [arg2] "{r4}" (arg2),
50 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });64 : .{ .memory = true, .cr0 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
51}65}
5266
53pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {67pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
68 // These registers are both inputs and clobbers.
69 var r0_out: usize = undefined;
70 var r4_out: usize = undefined;
71 var r5_out: usize = undefined;
54 return asm volatile (72 return asm volatile (
55 \\ sc73 \\ sc
56 \\ bns+ 1f74 \\ bns+ 1f
57 \\ neg 3, 375 \\ neg 3, 3
58 \\ 1:76 \\ 1:
59 : [ret] "={r3}" (-> usize),77 : [ret] "={r3}" (-> usize),
78 [r0_out] "={r0}" (r0_out),
79 [r4_out] "={r4}" (r4_out),
80 [r5_out] "={r5}" (r5_out),
60 : [number] "{r0}" (@intFromEnum(number)),81 : [number] "{r0}" (@intFromEnum(number)),
61 [arg1] "{r3}" (arg1),82 [arg1] "{r3}" (arg1),
62 [arg2] "{r4}" (arg2),83 [arg2] "{r4}" (arg2),
63 [arg3] "{r5}" (arg3),84 [arg3] "{r5}" (arg3),
64 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });85 : .{ .memory = true, .cr0 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
65}86}
6687
67pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {88pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89 // These registers are both inputs and clobbers.
90 var r0_out: usize = undefined;
91 var r4_out: usize = undefined;
92 var r5_out: usize = undefined;
93 var r6_out: usize = undefined;
68 return asm volatile (94 return asm volatile (
69 \\ sc95 \\ sc
70 \\ bns+ 1f96 \\ bns+ 1f
71 \\ neg 3, 397 \\ neg 3, 3
72 \\ 1:98 \\ 1:
73 : [ret] "={r3}" (-> usize),99 : [ret] "={r3}" (-> usize),
100 [r0_out] "={r0}" (r0_out),
101 [r4_out] "={r4}" (r4_out),
102 [r5_out] "={r5}" (r5_out),
103 [r6_out] "={r6}" (r6_out),
74 : [number] "{r0}" (@intFromEnum(number)),104 : [number] "{r0}" (@intFromEnum(number)),
75 [arg1] "{r3}" (arg1),105 [arg1] "{r3}" (arg1),
76 [arg2] "{r4}" (arg2),106 [arg2] "{r4}" (arg2),
77 [arg3] "{r5}" (arg3),107 [arg3] "{r5}" (arg3),
78 [arg4] "{r6}" (arg4),108 [arg4] "{r6}" (arg4),
79 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });109 : .{ .memory = true, .cr0 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
80}110}
81111
82pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {112pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
113 // These registers are both inputs and clobbers.
114 var r0_out: usize = undefined;
115 var r4_out: usize = undefined;
116 var r5_out: usize = undefined;
117 var r6_out: usize = undefined;
118 var r7_out: usize = undefined;
83 return asm volatile (119 return asm volatile (
84 \\ sc120 \\ sc
85 \\ bns+ 1f121 \\ bns+ 1f
86 \\ neg 3, 3122 \\ neg 3, 3
87 \\ 1:123 \\ 1:
88 : [ret] "={r3}" (-> usize),124 : [ret] "={r3}" (-> usize),
125 [r0_out] "={r0}" (r0_out),
126 [r4_out] "={r4}" (r4_out),
127 [r5_out] "={r5}" (r5_out),
128 [r6_out] "={r6}" (r6_out),
129 [r7_out] "={r7}" (r7_out),
89 : [number] "{r0}" (@intFromEnum(number)),130 : [number] "{r0}" (@intFromEnum(number)),
90 [arg1] "{r3}" (arg1),131 [arg1] "{r3}" (arg1),
91 [arg2] "{r4}" (arg2),132 [arg2] "{r4}" (arg2),
92 [arg3] "{r5}" (arg3),133 [arg3] "{r5}" (arg3),
93 [arg4] "{r6}" (arg4),134 [arg4] "{r6}" (arg4),
94 [arg5] "{r7}" (arg5),135 [arg5] "{r7}" (arg5),
95 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });136 : .{ .memory = true, .cr0 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
96}137}
97138
98pub fn syscall6(139pub fn syscall6(
...@@ -104,12 +145,25 @@ pub fn syscall6(...@@ -104,12 +145,25 @@ pub fn syscall6(
104 arg5: usize,145 arg5: usize,
105 arg6: usize,146 arg6: usize,
106) usize {147) usize {
148 // These registers are both inputs and clobbers.
149 var r0_out: usize = undefined;
150 var r4_out: usize = undefined;
151 var r5_out: usize = undefined;
152 var r6_out: usize = undefined;
153 var r7_out: usize = undefined;
154 var r8_out: usize = undefined;
107 return asm volatile (155 return asm volatile (
108 \\ sc156 \\ sc
109 \\ bns+ 1f157 \\ bns+ 1f
110 \\ neg 3, 3158 \\ neg 3, 3
111 \\ 1:159 \\ 1:
112 : [ret] "={r3}" (-> usize),160 : [ret] "={r3}" (-> usize),
161 [r0_out] "={r0}" (r0_out),
162 [r4_out] "={r4}" (r4_out),
163 [r5_out] "={r5}" (r5_out),
164 [r6_out] "={r6}" (r6_out),
165 [r7_out] "={r7}" (r7_out),
166 [r8_out] "={r8}" (r8_out),
113 : [number] "{r0}" (@intFromEnum(number)),167 : [number] "{r0}" (@intFromEnum(number)),
114 [arg1] "{r3}" (arg1),168 [arg1] "{r3}" (arg1),
115 [arg2] "{r4}" (arg2),169 [arg2] "{r4}" (arg2),
...@@ -117,7 +171,7 @@ pub fn syscall6(...@@ -117,7 +171,7 @@ pub fn syscall6(
117 [arg4] "{r6}" (arg4),171 [arg4] "{r6}" (arg4),
118 [arg5] "{r7}" (arg5),172 [arg5] "{r7}" (arg5),
119 [arg6] "{r8}" (arg6),173 [arg6] "{r8}" (arg6),
120 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });174 : .{ .memory = true, .cr0 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
121}175}
122176
123pub fn clone() callconv(.naked) usize {177pub fn clone() callconv(.naked) usize {
lib/std/os/linux/powerpc64.zig+61-7
...@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;...@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;
15const timespec = linux.timespec;15const timespec = linux.timespec;
1616
17pub fn syscall0(number: SYS) usize {17pub fn syscall0(number: SYS) usize {
18 // r0 is both an input register and a clobber. musl and glibc achieve this with
19 // a "+" constraint, which isn't supported in Zig, so instead we separately list
20 // r0 as both an input and an output. (Listing it as an input and a clobber would
21 // cause the C backend to emit invalid code; see #25209.)
22 var r0_out: usize = undefined;
18 return asm volatile (23 return asm volatile (
19 \\ sc24 \\ sc
20 \\ bns+ 1f25 \\ bns+ 1f
21 \\ neg 3, 326 \\ neg 3, 3
22 \\ 1:27 \\ 1:
23 : [ret] "={r3}" (-> usize),28 : [ret] "={r3}" (-> usize),
29 [r0_out] "={r0}" (r0_out),
24 : [number] "{r0}" (@intFromEnum(number)),30 : [number] "{r0}" (@intFromEnum(number)),
25 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });31 : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
26}32}
2733
28pub fn syscall1(number: SYS, arg1: usize) usize {34pub fn syscall1(number: SYS, arg1: usize) usize {
35 // r0 is both an input and a clobber.
36 var r0_out: usize = undefined;
29 return asm volatile (37 return asm volatile (
30 \\ sc38 \\ sc
31 \\ bns+ 1f39 \\ bns+ 1f
32 \\ neg 3, 340 \\ neg 3, 3
33 \\ 1:41 \\ 1:
34 : [ret] "={r3}" (-> usize),42 : [ret] "={r3}" (-> usize),
43 [r0_out] "={r0}" (r0_out),
35 : [number] "{r0}" (@intFromEnum(number)),44 : [number] "{r0}" (@intFromEnum(number)),
36 [arg1] "{r3}" (arg1),45 [arg1] "{r3}" (arg1),
37 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });46 : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
38}47}
3948
40pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {49pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
50 // These registers are both inputs and clobbers.
51 var r0_out: usize = undefined;
52 var r4_out: usize = undefined;
41 return asm volatile (53 return asm volatile (
42 \\ sc54 \\ sc
43 \\ bns+ 1f55 \\ bns+ 1f
44 \\ neg 3, 356 \\ neg 3, 3
45 \\ 1:57 \\ 1:
46 : [ret] "={r3}" (-> usize),58 : [ret] "={r3}" (-> usize),
59 [r0_out] "={r0}" (r0_out),
60 [r4_out] "={r4}" (r4_out),
47 : [number] "{r0}" (@intFromEnum(number)),61 : [number] "{r0}" (@intFromEnum(number)),
48 [arg1] "{r3}" (arg1),62 [arg1] "{r3}" (arg1),
49 [arg2] "{r4}" (arg2),63 [arg2] "{r4}" (arg2),
50 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });64 : .{ .memory = true, .cr0 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
51}65}
5266
53pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {67pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
68 // These registers are both inputs and clobbers.
69 var r0_out: usize = undefined;
70 var r4_out: usize = undefined;
71 var r5_out: usize = undefined;
54 return asm volatile (72 return asm volatile (
55 \\ sc73 \\ sc
56 \\ bns+ 1f74 \\ bns+ 1f
57 \\ neg 3, 375 \\ neg 3, 3
58 \\ 1:76 \\ 1:
59 : [ret] "={r3}" (-> usize),77 : [ret] "={r3}" (-> usize),
78 [r0_out] "={r0}" (r0_out),
79 [r4_out] "={r4}" (r4_out),
80 [r5_out] "={r5}" (r5_out),
60 : [number] "{r0}" (@intFromEnum(number)),81 : [number] "{r0}" (@intFromEnum(number)),
61 [arg1] "{r3}" (arg1),82 [arg1] "{r3}" (arg1),
62 [arg2] "{r4}" (arg2),83 [arg2] "{r4}" (arg2),
63 [arg3] "{r5}" (arg3),84 [arg3] "{r5}" (arg3),
64 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });85 : .{ .memory = true, .cr0 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
65}86}
6687
67pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {88pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89 // These registers are both inputs and clobbers.
90 var r0_out: usize = undefined;
91 var r4_out: usize = undefined;
92 var r5_out: usize = undefined;
93 var r6_out: usize = undefined;
68 return asm volatile (94 return asm volatile (
69 \\ sc95 \\ sc
70 \\ bns+ 1f96 \\ bns+ 1f
71 \\ neg 3, 397 \\ neg 3, 3
72 \\ 1:98 \\ 1:
73 : [ret] "={r3}" (-> usize),99 : [ret] "={r3}" (-> usize),
100 [r0_out] "={r0}" (r0_out),
101 [r4_out] "={r4}" (r4_out),
102 [r5_out] "={r5}" (r5_out),
103 [r6_out] "={r6}" (r6_out),
74 : [number] "{r0}" (@intFromEnum(number)),104 : [number] "{r0}" (@intFromEnum(number)),
75 [arg1] "{r3}" (arg1),105 [arg1] "{r3}" (arg1),
76 [arg2] "{r4}" (arg2),106 [arg2] "{r4}" (arg2),
77 [arg3] "{r5}" (arg3),107 [arg3] "{r5}" (arg3),
78 [arg4] "{r6}" (arg4),108 [arg4] "{r6}" (arg4),
79 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });109 : .{ .memory = true, .cr0 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
80}110}
81111
82pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {112pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
113 // These registers are both inputs and clobbers.
114 var r0_out: usize = undefined;
115 var r4_out: usize = undefined;
116 var r5_out: usize = undefined;
117 var r6_out: usize = undefined;
118 var r7_out: usize = undefined;
83 return asm volatile (119 return asm volatile (
84 \\ sc120 \\ sc
85 \\ bns+ 1f121 \\ bns+ 1f
86 \\ neg 3, 3122 \\ neg 3, 3
87 \\ 1:123 \\ 1:
88 : [ret] "={r3}" (-> usize),124 : [ret] "={r3}" (-> usize),
125 [r0_out] "={r0}" (r0_out),
126 [r4_out] "={r4}" (r4_out),
127 [r5_out] "={r5}" (r5_out),
128 [r6_out] "={r6}" (r6_out),
129 [r7_out] "={r7}" (r7_out),
89 : [number] "{r0}" (@intFromEnum(number)),130 : [number] "{r0}" (@intFromEnum(number)),
90 [arg1] "{r3}" (arg1),131 [arg1] "{r3}" (arg1),
91 [arg2] "{r4}" (arg2),132 [arg2] "{r4}" (arg2),
92 [arg3] "{r5}" (arg3),133 [arg3] "{r5}" (arg3),
93 [arg4] "{r6}" (arg4),134 [arg4] "{r6}" (arg4),
94 [arg5] "{r7}" (arg5),135 [arg5] "{r7}" (arg5),
95 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });136 : .{ .memory = true, .cr0 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
96}137}
97138
98pub fn syscall6(139pub fn syscall6(
...@@ -104,12 +145,25 @@ pub fn syscall6(...@@ -104,12 +145,25 @@ pub fn syscall6(
104 arg5: usize,145 arg5: usize,
105 arg6: usize,146 arg6: usize,
106) usize {147) usize {
148 // These registers are both inputs and clobbers.
149 var r0_out: usize = undefined;
150 var r4_out: usize = undefined;
151 var r5_out: usize = undefined;
152 var r6_out: usize = undefined;
153 var r7_out: usize = undefined;
154 var r8_out: usize = undefined;
107 return asm volatile (155 return asm volatile (
108 \\ sc156 \\ sc
109 \\ bns+ 1f157 \\ bns+ 1f
110 \\ neg 3, 3158 \\ neg 3, 3
111 \\ 1:159 \\ 1:
112 : [ret] "={r3}" (-> usize),160 : [ret] "={r3}" (-> usize),
161 [r0_out] "={r0}" (r0_out),
162 [r4_out] "={r4}" (r4_out),
163 [r5_out] "={r5}" (r5_out),
164 [r6_out] "={r6}" (r6_out),
165 [r7_out] "={r7}" (r7_out),
166 [r8_out] "={r8}" (r8_out),
113 : [number] "{r0}" (@intFromEnum(number)),167 : [number] "{r0}" (@intFromEnum(number)),
114 [arg1] "{r3}" (arg1),168 [arg1] "{r3}" (arg1),
115 [arg2] "{r4}" (arg2),169 [arg2] "{r4}" (arg2),
...@@ -117,7 +171,7 @@ pub fn syscall6(...@@ -117,7 +171,7 @@ pub fn syscall6(
117 [arg4] "{r6}" (arg4),171 [arg4] "{r6}" (arg4),
118 [arg5] "{r7}" (arg5),172 [arg5] "{r7}" (arg5),
119 [arg6] "{r8}" (arg6),173 [arg6] "{r8}" (arg6),
120 : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });174 : .{ .memory = true, .cr0 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
121}175}
122176
123pub fn clone() callconv(.naked) usize {177pub fn clone() callconv(.naked) usize {