authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 01:56:20+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 11:16:31+02:00
logb8d776928a0b0092830ee632b1c57c8bcf9391ea
tree5f30b527977d152cad713f19018c69c7a71124c5
parentf3da54f53c1db1484b00657de18e3677358549cd
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std: make all MIPS inline asm safe for MIPS I

MIPS I has load hazards so we need to insert nops in a few places. This is not a problem for MIPS II and later. While doing this, I also touched up all the inline asm to use ABI register aliases and a consistent formatting convention. Also fixed a few places that didn't properly check if the syscall return value should be negated.

5 files changed, 223 insertions(+), 232 deletions(-)

lib/std/os/linux/mips.zig+78-84
...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
5pub fn syscall0(number: SYS) u32 {5pub fn syscall0(number: SYS) u32 {
6 return asm volatile (6 return asm volatile (
7 \\ syscall7 \\ syscall
8 \\ beq $7, $zero, 1f8 \\ beq $a3, $zero, 1f
9 \\ blez $2, 1f9 \\ blez $v0, 1f
10 \\ subu $2, $0, $210 \\ subu $v0, $zero, $v0
11 \\ 1:11 \\1:
12 : [ret] "={$2}" (-> u32),12 : [ret] "={$2}" (-> u32),
13 : [number] "{$2}" (@intFromEnum(number)),13 : [number] "{$2}" (@intFromEnum(number)),
14 : .{ .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 });14 : .{ .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 });
...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {
1616
17pub fn syscall_pipe(fd: *[2]i32) u32 {17pub fn syscall_pipe(fd: *[2]i32) u32 {
18 return asm volatile (18 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
21 \\ syscall19 \\ syscall
22 \\ beq $7, $zero, 1f20 \\ beq $a3, $zero, 1f
23 \\ nop21 \\ blez $v0, 2f
22 \\ subu $v0, $zero, $v0
24 \\ b 2f23 \\ b 2f
25 \\ subu $2, $0, $224 \\1:
26 \\ 1:25 \\ sw $v0, 0($a0)
27 \\ sw $2, 0($4)26 \\ sw $v1, 4($a0)
28 \\ sw $3, 4($4)27 \\2:
29 \\ 2:
30 : [ret] "={$2}" (-> u32),28 : [ret] "={$2}" (-> u32),
31 : [number] "{$2}" (@intFromEnum(SYS.pipe)),29 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
32 [fd] "{$4}" (fd),30 [fd] "{$4}" (fd),
...@@ -36,10 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {...@@ -36,10 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
36pub fn syscall1(number: SYS, arg1: u32) u32 {34pub fn syscall1(number: SYS, arg1: u32) u32 {
37 return asm volatile (35 return asm volatile (
38 \\ syscall36 \\ syscall
39 \\ beq $7, $zero, 1f37 \\ beq $a3, $zero, 1f
40 \\ blez $2, 1f38 \\ blez $v0, 1f
41 \\ subu $2, $0, $239 \\ subu $v0, $zero, $v0
42 \\ 1:40 \\1:
43 : [ret] "={$2}" (-> u32),41 : [ret] "={$2}" (-> u32),
44 : [number] "{$2}" (@intFromEnum(number)),42 : [number] "{$2}" (@intFromEnum(number)),
45 [arg1] "{$4}" (arg1),43 [arg1] "{$4}" (arg1),
...@@ -49,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {...@@ -49,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
49pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {47pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
50 return asm volatile (48 return asm volatile (
51 \\ syscall49 \\ syscall
52 \\ beq $7, $zero, 1f50 \\ beq $a3, $zero, 1f
53 \\ blez $2, 1f51 \\ blez $v0, 1f
54 \\ subu $2, $0, $252 \\ subu $v0, $zero, $v0
55 \\ 1:53 \\1:
56 : [ret] "={$2}" (-> u32),54 : [ret] "={$2}" (-> u32),
57 : [number] "{$2}" (@intFromEnum(number)),55 : [number] "{$2}" (@intFromEnum(number)),
58 [arg1] "{$4}" (arg1),56 [arg1] "{$4}" (arg1),
...@@ -63,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {...@@ -63,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
63pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {61pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
64 return asm volatile (62 return asm volatile (
65 \\ syscall63 \\ syscall
66 \\ beq $7, $zero, 1f64 \\ beq $a3, $zero, 1f
67 \\ blez $2, 1f65 \\ blez $v0, 1f
68 \\ subu $2, $0, $266 \\ subu $v0, $zero, $v0
69 \\ 1:67 \\1:
70 : [ret] "={$2}" (-> u32),68 : [ret] "={$2}" (-> u32),
71 : [number] "{$2}" (@intFromEnum(number)),69 : [number] "{$2}" (@intFromEnum(number)),
72 [arg1] "{$4}" (arg1),70 [arg1] "{$4}" (arg1),
...@@ -78,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {...@@ -78,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
78pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {76pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
79 return asm volatile (77 return asm volatile (
80 \\ syscall78 \\ syscall
81 \\ beq $7, $zero, 1f79 \\ beq $a3, $zero, 1f
82 \\ blez $2, 1f80 \\ blez $v0, 1f
83 \\ subu $2, $0, $281 \\ subu $v0, $zero, $v0
84 \\ 1:82 \\1:
85 : [ret] "={$2}" (-> u32),83 : [ret] "={$2}" (-> u32),
86 : [number] "{$2}" (@intFromEnum(number)),84 : [number] "{$2}" (@intFromEnum(number)),
87 [arg1] "{$4}" (arg1),85 [arg1] "{$4}" (arg1),
...@@ -91,17 +89,19 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {...@@ -91,17 +89,19 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
91 : .{ .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 });89 : .{ .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 });
92}90}
9391
92// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
93// the first four arguments even though they're passed in $a0-$a3.
94
94pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {95pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
95 return asm volatile (96 return asm volatile (
96 \\ .set noat
97 \\ subu $sp, $sp, 2497 \\ subu $sp, $sp, 24
98 \\ sw %[arg5], 16($sp)98 \\ sw %[arg5], 16($sp)
99 \\ syscall99 \\ syscall
100 \\ addu $sp, $sp, 24100 \\ addu $sp, $sp, 24
101 \\ beq $7, $zero, 1f101 \\ beq $a3, $zero, 1f
102 \\ blez $2, 1f102 \\ blez $v0, 1f
103 \\ subu $2, $0, $2103 \\ subu $v0, $zero, $v0
104 \\ 1:104 \\1:
105 : [ret] "={$2}" (-> u32),105 : [ret] "={$2}" (-> u32),
106 : [number] "{$2}" (@intFromEnum(number)),106 : [number] "{$2}" (@intFromEnum(number)),
107 [arg1] "{$4}" (arg1),107 [arg1] "{$4}" (arg1),
...@@ -112,9 +112,6 @@ pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u...@@ -112,9 +112,6 @@ pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u
112 : .{ .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 });112 : .{ .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 });
113}113}
114114
115// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
116// the first four arguments even though they're passed in $a0-$a3.
117
118pub fn syscall6(115pub fn syscall6(
119 number: SYS,116 number: SYS,
120 arg1: u32,117 arg1: u32,
...@@ -125,16 +122,15 @@ pub fn syscall6(...@@ -125,16 +122,15 @@ pub fn syscall6(
125 arg6: u32,122 arg6: u32,
126) u32 {123) u32 {
127 return asm volatile (124 return asm volatile (
128 \\ .set noat
129 \\ subu $sp, $sp, 24125 \\ subu $sp, $sp, 24
130 \\ sw %[arg5], 16($sp)126 \\ sw %[arg5], 16($sp)
131 \\ sw %[arg6], 20($sp)127 \\ sw %[arg6], 20($sp)
132 \\ syscall128 \\ syscall
133 \\ addu $sp, $sp, 24129 \\ addu $sp, $sp, 24
134 \\ beq $7, $zero, 1f130 \\ beq $a3, $zero, 1f
135 \\ blez $2, 1f131 \\ blez $v0, 1f
136 \\ subu $2, $0, $2132 \\ subu $v0, $zero, $v0
137 \\ 1:133 \\1:
138 : [ret] "={$2}" (-> u32),134 : [ret] "={$2}" (-> u32),
139 : [number] "{$2}" (@intFromEnum(number)),135 : [number] "{$2}" (@intFromEnum(number)),
140 [arg1] "{$4}" (arg1),136 [arg1] "{$4}" (arg1),
...@@ -157,17 +153,16 @@ pub fn syscall7(...@@ -157,17 +153,16 @@ pub fn syscall7(
157 arg7: u32,153 arg7: u32,
158) u32 {154) u32 {
159 return asm volatile (155 return asm volatile (
160 \\ .set noat
161 \\ subu $sp, $sp, 32156 \\ subu $sp, $sp, 32
162 \\ sw %[arg5], 16($sp)157 \\ sw %[arg5], 16($sp)
163 \\ sw %[arg6], 20($sp)158 \\ sw %[arg6], 20($sp)
164 \\ sw %[arg7], 24($sp)159 \\ sw %[arg7], 24($sp)
165 \\ syscall160 \\ syscall
166 \\ addu $sp, $sp, 32161 \\ addu $sp, $sp, 32
167 \\ beq $7, $zero, 1f162 \\ beq $a3, $zero, 1f
168 \\ blez $2, 1f163 \\ blez $v0, 1f
169 \\ subu $2, $0, $2164 \\ subu $v0, $zero, $v0
170 \\ 1:165 \\1:
171 : [ret] "={$2}" (-> u32),166 : [ret] "={$2}" (-> u32),
172 : [number] "{$2}" (@intFromEnum(number)),167 : [number] "{$2}" (@intFromEnum(number)),
173 [arg1] "{$4}" (arg1),168 [arg1] "{$4}" (arg1),
...@@ -182,52 +177,51 @@ pub fn syscall7(...@@ -182,52 +177,51 @@ pub fn syscall7(
182177
183pub fn clone() callconv(.naked) u32 {178pub fn clone() callconv(.naked) u32 {
184 // __clone(func, stack, flags, arg, ptid, tls, ctid)179 // __clone(func, stack, flags, arg, ptid, tls, ctid)
185 // 3, 4, 5, 6, 7, 8, 9180 // a0, a1, a2, a3, +0, +4, +8
186 //181 //
187 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)182 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
188 // 2 4, 5, 6, 7, 8183 // v0 a0, a1, a2, a3, +0
189 asm volatile (184 asm volatile (
190 \\ # Save function pointer and argument pointer on new thread stack185 \\ # Save function pointer and argument pointer on new thread stack
191 \\ and $5, $5, -8186 \\ and $a1, $a1, -8
192 \\ subu $5, $5, 16187 \\ subu $a1, $a1, 16
193 \\ sw $4, 0($5)188 \\ sw $a0, 0($a1)
194 \\ sw $7, 4($5)189 \\ sw $a3, 4($a1)
195 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)190 \\
196 \\ move $4, $6191 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
197 \\ lw $6, 16($sp)192 \\ move $a0, $a2
198 \\ lw $7, 20($sp)193 \\ lw $a2, 16($sp)
199 \\ lw $9, 24($sp)194 \\ lw $a3, 20($sp)
200 \\ subu $sp, $sp, 16195 \\ lw $t1, 24($sp)
201 \\ sw $9, 16($sp)196 \\ subu $sp, $sp, 16
202 \\ li $2, 4120 # SYS_clone197 \\ sw $t1, 16($sp)
203 \\ syscall198 \\ li $v0, 4120 # SYS_clone
204 \\ beq $7, $0, 1f199 \\ syscall
205 \\ nop200 \\ beq $a3, $zero, 1f
206 \\ addu $sp, $sp, 16201 \\ blez $v0, 2f
207 \\ jr $ra202 \\ subu $v0, $zero, $v0
208 \\ subu $2, $0, $2203 \\ b 2f
209 \\1:
210 \\ beq $2, $0, 1f
211 \\ nop
212 \\ addu $sp, $sp, 16
213 \\ jr $ra
214 \\ nop
215 \\1:204 \\1:
205 \\ beq $v0, $zero, 3f
206 \\2:
207 \\ addu $sp, $sp, 16
208 \\ jr $ra
209 \\3:
216 );210 );
217 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (211 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
218 \\ .cfi_undefined $ra212 \\ .cfi_undefined $ra
219 );213 );
220 asm volatile (214 asm volatile (
221 \\ move $fp, $zero215 \\ move $fp, $zero
222 \\ move $ra, $zero216 \\ move $ra, $zero
223 \\217 \\
224 \\ lw $25, 0($sp)218 \\ lw $t9, 0($sp)
225 \\ lw $4, 4($sp)219 \\ lw $a0, 4($sp)
226 \\ jalr $25220 \\ jalr $t9
227 \\ nop221 \\
228 \\ move $4, $2222 \\ move $a0, $v0
229 \\ li $2, 4001 # SYS_exit223 \\ li $v0, 4001 # SYS_exit
230 \\ syscall224 \\ syscall
231 );225 );
232}226}
233227
lib/std/os/linux/mips64.zig+64-67
...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
5pub fn syscall0(number: SYS) u64 {5pub fn syscall0(number: SYS) u64 {
6 return asm volatile (6 return asm volatile (
7 \\ syscall7 \\ syscall
8 \\ beq $7, $zero, 1f8 \\ beq $a3, $zero, 1f
9 \\ blez $2, 1f9 \\ blez $v0, 1f
10 \\ dsubu $2, $0, $210 \\ dsubu $v0, $zero, $v0
11 \\ 1:11 \\1:
12 : [ret] "={$2}" (-> u64),12 : [ret] "={$2}" (-> u64),
13 : [number] "{$2}" (@intFromEnum(number)),13 : [number] "{$2}" (@intFromEnum(number)),
14 : .{ .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 });14 : .{ .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 });
...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u64 {...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u64 {
1616
17pub fn syscall_pipe(fd: *[2]i32) u64 {17pub fn syscall_pipe(fd: *[2]i32) u64 {
18 return asm volatile (18 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
21 \\ syscall19 \\ syscall
22 \\ beq $7, $zero, 1f20 \\ beq $a3, $zero, 1f
23 \\ nop21 \\ blez $v0, 2f
22 \\ dsubu $v0, $zero, $v0
24 \\ b 2f23 \\ b 2f
25 \\ subu $2, $0, $224 \\1:
26 \\ 1:25 \\ sw $v0, 0($a0)
27 \\ sw $2, 0($4)26 \\ sw $v1, 4($a0)
28 \\ sw $3, 4($4)27 \\2:
29 \\ 2:
30 : [ret] "={$2}" (-> u64),28 : [ret] "={$2}" (-> u64),
31 : [number] "{$2}" (@intFromEnum(SYS.pipe)),29 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
32 [fd] "{$4}" (fd),30 [fd] "{$4}" (fd),
...@@ -36,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u64 {...@@ -36,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u64 {
36pub fn syscall1(number: SYS, arg1: u64) u64 {34pub fn syscall1(number: SYS, arg1: u64) u64 {
37 return asm volatile (35 return asm volatile (
38 \\ syscall36 \\ syscall
39 \\ beq $7, $zero, 1f37 \\ beq $a3, $zero, 1f
40 \\ blez $2, 1f38 \\ blez $v0, 1f
41 \\ nop39 \\ dsubu $v0, $zero, $v0
42 \\ dsubu $2, $0, $240 \\1:
43 \\ 1:
44 : [ret] "={$2}" (-> u64),41 : [ret] "={$2}" (-> u64),
45 : [number] "{$2}" (@intFromEnum(number)),42 : [number] "{$2}" (@intFromEnum(number)),
46 [arg1] "{$4}" (arg1),43 [arg1] "{$4}" (arg1),
...@@ -50,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u64) u64 {...@@ -50,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u64) u64 {
50pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {47pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
51 return asm volatile (48 return asm volatile (
52 \\ syscall49 \\ syscall
53 \\ beq $7, $zero, 1f50 \\ beq $a3, $zero, 1f
54 \\ blez $2, 1f51 \\ blez $v0, 1f
55 \\ dsubu $2, $0, $252 \\ dsubu $v0, $zero, $v0
56 \\ 1:53 \\1:
57 : [ret] "={$2}" (-> u64),54 : [ret] "={$2}" (-> u64),
58 : [number] "{$2}" (@intFromEnum(number)),55 : [number] "{$2}" (@intFromEnum(number)),
59 [arg1] "{$4}" (arg1),56 [arg1] "{$4}" (arg1),
...@@ -64,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {...@@ -64,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
64pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {61pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
65 return asm volatile (62 return asm volatile (
66 \\ syscall63 \\ syscall
67 \\ beq $7, $zero, 1f64 \\ beq $a3, $zero, 1f
68 \\ blez $2, 1f65 \\ blez $v0, 1f
69 \\ dsubu $2, $0, $266 \\ dsubu $v0, $zero, $v0
70 \\ 1:67 \\1:
71 : [ret] "={$2}" (-> u64),68 : [ret] "={$2}" (-> u64),
72 : [number] "{$2}" (@intFromEnum(number)),69 : [number] "{$2}" (@intFromEnum(number)),
73 [arg1] "{$4}" (arg1),70 [arg1] "{$4}" (arg1),
...@@ -79,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {...@@ -79,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
79pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {76pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
80 return asm volatile (77 return asm volatile (
81 \\ syscall78 \\ syscall
82 \\ beq $7, $zero, 1f79 \\ beq $a3, $zero, 1f
83 \\ blez $2, 1f80 \\ blez $v0, 1f
84 \\ dsubu $2, $0, $281 \\ dsubu $v0, $zero, $v0
85 \\ 1:82 \\1:
86 : [ret] "={$2}" (-> u64),83 : [ret] "={$2}" (-> u64),
87 : [number] "{$2}" (@intFromEnum(number)),84 : [number] "{$2}" (@intFromEnum(number)),
88 [arg1] "{$4}" (arg1),85 [arg1] "{$4}" (arg1),
...@@ -95,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {...@@ -95,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
95pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {92pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
96 return asm volatile (93 return asm volatile (
97 \\ syscall94 \\ syscall
98 \\ beq $7, $zero, 1f95 \\ beq $a3, $zero, 1f
99 \\ blez $2, 1f96 \\ blez $v0, 1f
100 \\ dsubu $2, $0, $297 \\ dsubu $v0, $zero, $v0
101 \\ 1:98 \\1:
102 : [ret] "={$2}" (-> u64),99 : [ret] "={$2}" (-> u64),
103 : [number] "{$2}" (@intFromEnum(number)),100 : [number] "{$2}" (@intFromEnum(number)),
104 [arg1] "{$4}" (arg1),101 [arg1] "{$4}" (arg1),
...@@ -120,10 +117,10 @@ pub fn syscall6(...@@ -120,10 +117,10 @@ pub fn syscall6(
120) u64 {117) u64 {
121 return asm volatile (118 return asm volatile (
122 \\ syscall119 \\ syscall
123 \\ beq $7, $zero, 1f120 \\ beq $a3, $zero, 1f
124 \\ blez $2, 1f121 \\ blez $v0, 1f
125 \\ dsubu $2, $0, $2122 \\ dsubu $v0, $zero, $v0
126 \\ 1:123 \\1:
127 : [ret] "={$2}" (-> u64),124 : [ret] "={$2}" (-> u64),
128 : [number] "{$2}" (@intFromEnum(number)),125 : [number] "{$2}" (@intFromEnum(number)),
129 [arg1] "{$4}" (arg1),126 [arg1] "{$4}" (arg1),
...@@ -147,10 +144,10 @@ pub fn syscall7(...@@ -147,10 +144,10 @@ pub fn syscall7(
147) u64 {144) u64 {
148 return asm volatile (145 return asm volatile (
149 \\ syscall146 \\ syscall
150 \\ beq $7, $zero, 1f147 \\ beq $a3, $zero, 1f
151 \\ blez $2, 1f148 \\ blez $v0, 1f
152 \\ dsubu $2, $0, $2149 \\ dsubu $v0, $zero, $v0
153 \\ 1:150 \\1:
154 : [ret] "={$2}" (-> u64),151 : [ret] "={$2}" (-> u64),
155 : [number] "{$2}" (@intFromEnum(number)),152 : [number] "{$2}" (@intFromEnum(number)),
156 [arg1] "{$4}" (arg1),153 [arg1] "{$4}" (arg1),
...@@ -165,33 +162,33 @@ pub fn syscall7(...@@ -165,33 +162,33 @@ pub fn syscall7(
165162
166pub fn clone() callconv(.naked) u64 {163pub fn clone() callconv(.naked) u64 {
167 // __clone(func, stack, flags, arg, ptid, tls, ctid)164 // __clone(func, stack, flags, arg, ptid, tls, ctid)
168 // 3, 4, 5, 6, 7, 8, 9165 // a0, a1, a2, a3, a4, a5, a6
169 //166 //
170 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)167 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
171 // 2 4, 5, 6, 7, 8168 // v0 a0, a1, a2, a3, a4
172 asm volatile (169 asm volatile (
173 \\ # Save function pointer and argument pointer on new thread stack170 \\ # Save function pointer and argument pointer on new thread stack
174 \\ and $5, $5, -16171 \\ and $a1, $a1, -16
175 \\ dsubu $5, $5, 16172 \\ dsubu $a1, $a1, 16
176 \\ sd $4, 0($5)173 \\ sd $a0, 0($a1)
177 \\ sd $7, 8($5)174 \\ sd $a3, 8($a1)
175 \\
178 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)176 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
179 \\ move $4, $6177 \\ move $a0, $a2
180 \\ move $6, $8178 \\ move $a2, $a4
181 \\ move $7, $9179 \\ move $a3, $a5
182 \\ move $8, $10180 \\ move $a4, $a6
183 \\ li $2, 5055 # SYS_clone181 \\ li $v0, 5055 # SYS_clone
184 \\ syscall182 \\ syscall
185 \\ beq $7, $0, 1f183 \\ beq $a3, $zero, 1f
186 \\ nop184 \\ blez $v0, 2f
187 \\ jr $ra185 \\ dsubu $v0, $zero, $v0
188 \\ dsubu $2, $0, $2186 \\ b 2f
189 \\1:187 \\1:
190 \\ beq $2, $0, 1f188 \\ beq $v0, $zero, 3f
191 \\ nop189 \\2:
192 \\ jr $ra190 \\ jr $ra
193 \\ nop191 \\3:
194 \\1:
195 );192 );
196 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (193 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
197 \\ .cfi_undefined $ra194 \\ .cfi_undefined $ra
...@@ -200,12 +197,12 @@ pub fn clone() callconv(.naked) u64 {...@@ -200,12 +197,12 @@ pub fn clone() callconv(.naked) u64 {
200 \\ move $fp, $zero197 \\ move $fp, $zero
201 \\ move $ra, $zero198 \\ move $ra, $zero
202 \\199 \\
203 \\ ld $25, 0($sp)200 \\ ld $t9, 0($sp)
204 \\ ld $4, 8($sp)201 \\ ld $a0, 8($sp)
205 \\ jalr $25202 \\ jalr $t9
206 \\ nop203 \\
207 \\ move $4, $2204 \\ move $a0, $v0
208 \\ li $2, 5058 # SYS_exit205 \\ li $v0, 5058 # SYS_exit
209 \\ syscall206 \\ syscall
210 );207 );
211}208}
lib/std/os/linux/mipsn32.zig+64-67
...@@ -7,10 +7,10 @@ const SYS = std.os.linux.SYS;...@@ -7,10 +7,10 @@ const SYS = std.os.linux.SYS;
7pub fn syscall0(number: SYS) u32 {7pub fn syscall0(number: SYS) u32 {
8 return asm volatile (8 return asm volatile (
9 \\ syscall9 \\ syscall
10 \\ beq $7, $zero, 1f10 \\ beq $a3, $zero, 1f
11 \\ blez $2, 1f11 \\ blez $v0, 1f
12 \\ dsubu $2, $0, $212 \\ dsubu $v0, $zero, $v0
13 \\ 1:13 \\1:
14 : [ret] "={$2}" (-> u32),14 : [ret] "={$2}" (-> u32),
15 : [number] "{$2}" (@intFromEnum(number)),15 : [number] "{$2}" (@intFromEnum(number)),
16 : .{ .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 });16 : .{ .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 });
...@@ -18,17 +18,15 @@ pub fn syscall0(number: SYS) u32 {...@@ -18,17 +18,15 @@ pub fn syscall0(number: SYS) u32 {
1818
19pub fn syscall_pipe(fd: *[2]i32) u32 {19pub fn syscall_pipe(fd: *[2]i32) u32 {
20 return asm volatile (20 return asm volatile (
21 \\ .set noat
22 \\ .set noreorder
23 \\ syscall21 \\ syscall
24 \\ beq $7, $zero, 1f22 \\ beq $a3, $zero, 1f
25 \\ nop23 \\ blez $v0, 2f
24 \\ dsubu $v0, $zero, $v0
26 \\ b 2f25 \\ b 2f
27 \\ subu $2, $0, $226 \\1:
28 \\ 1:27 \\ sw $v0, 0($a0)
29 \\ sw $2, 0($4)28 \\ sw $v1, 4($a0)
30 \\ sw $3, 4($4)29 \\2:
31 \\ 2:
32 : [ret] "={$2}" (-> u32),30 : [ret] "={$2}" (-> u32),
33 : [number] "{$2}" (@intFromEnum(SYS.pipe)),31 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
34 [fd] "{$4}" (fd),32 [fd] "{$4}" (fd),
...@@ -38,11 +36,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {...@@ -38,11 +36,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
38pub fn syscall1(number: SYS, arg1: u32) u32 {36pub fn syscall1(number: SYS, arg1: u32) u32 {
39 return asm volatile (37 return asm volatile (
40 \\ syscall38 \\ syscall
41 \\ beq $7, $zero, 1f39 \\ beq $a3, $zero, 1f
42 \\ blez $2, 1f40 \\ blez $v0, 1f
43 \\ nop41 \\ dsubu $v0, $zero, $v0
44 \\ dsubu $2, $0, $242 \\1:
45 \\ 1:
46 : [ret] "={$2}" (-> u32),43 : [ret] "={$2}" (-> u32),
47 : [number] "{$2}" (@intFromEnum(number)),44 : [number] "{$2}" (@intFromEnum(number)),
48 [arg1] "{$4}" (arg1),45 [arg1] "{$4}" (arg1),
...@@ -52,10 +49,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {...@@ -52,10 +49,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
52pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {49pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
53 return asm volatile (50 return asm volatile (
54 \\ syscall51 \\ syscall
55 \\ beq $7, $zero, 1f52 \\ beq $a3, $zero, 1f
56 \\ blez $2, 1f53 \\ blez $v0, 1f
57 \\ dsubu $2, $0, $254 \\ dsubu $v0, $zero, $v0
58 \\ 1:55 \\1:
59 : [ret] "={$2}" (-> u32),56 : [ret] "={$2}" (-> u32),
60 : [number] "{$2}" (@intFromEnum(number)),57 : [number] "{$2}" (@intFromEnum(number)),
61 [arg1] "{$4}" (arg1),58 [arg1] "{$4}" (arg1),
...@@ -66,10 +63,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {...@@ -66,10 +63,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
66pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {63pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
67 return asm volatile (64 return asm volatile (
68 \\ syscall65 \\ syscall
69 \\ beq $7, $zero, 1f66 \\ beq $a3, $zero, 1f
70 \\ blez $2, 1f67 \\ blez $v0, 1f
71 \\ dsubu $2, $0, $268 \\ dsubu $v0, $zero, $v0
72 \\ 1:69 \\1:
73 : [ret] "={$2}" (-> u32),70 : [ret] "={$2}" (-> u32),
74 : [number] "{$2}" (@intFromEnum(number)),71 : [number] "{$2}" (@intFromEnum(number)),
75 [arg1] "{$4}" (arg1),72 [arg1] "{$4}" (arg1),
...@@ -81,10 +78,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {...@@ -81,10 +78,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
81pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {78pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
82 return asm volatile (79 return asm volatile (
83 \\ syscall80 \\ syscall
84 \\ beq $7, $zero, 1f81 \\ beq $a3, $zero, 1f
85 \\ blez $2, 1f82 \\ blez $v0, 1f
86 \\ dsubu $2, $0, $283 \\ dsubu $v0, $zero, $v0
87 \\ 1:84 \\1:
88 : [ret] "={$2}" (-> u32),85 : [ret] "={$2}" (-> u32),
89 : [number] "{$2}" (@intFromEnum(number)),86 : [number] "{$2}" (@intFromEnum(number)),
90 [arg1] "{$4}" (arg1),87 [arg1] "{$4}" (arg1),
...@@ -97,10 +94,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {...@@ -97,10 +94,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
97pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {94pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
98 return asm volatile (95 return asm volatile (
99 \\ syscall96 \\ syscall
100 \\ beq $7, $zero, 1f97 \\ beq $a3, $zero, 1f
101 \\ blez $2, 1f98 \\ blez $v0, 1f
102 \\ dsubu $2, $0, $299 \\ dsubu $v0, $zero, $v0
103 \\ 1:100 \\1:
104 : [ret] "={$2}" (-> u32),101 : [ret] "={$2}" (-> u32),
105 : [number] "{$2}" (@intFromEnum(number)),102 : [number] "{$2}" (@intFromEnum(number)),
106 [arg1] "{$4}" (arg1),103 [arg1] "{$4}" (arg1),
...@@ -122,10 +119,10 @@ pub fn syscall6(...@@ -122,10 +119,10 @@ pub fn syscall6(
122) u32 {119) u32 {
123 return asm volatile (120 return asm volatile (
124 \\ syscall121 \\ syscall
125 \\ beq $7, $zero, 1f122 \\ beq $a3, $zero, 1f
126 \\ blez $2, 1f123 \\ blez $v0, 1f
127 \\ dsubu $2, $0, $2124 \\ dsubu $v0, $zero, $v0
128 \\ 1:125 \\1:
129 : [ret] "={$2}" (-> u32),126 : [ret] "={$2}" (-> u32),
130 : [number] "{$2}" (@intFromEnum(number)),127 : [number] "{$2}" (@intFromEnum(number)),
131 [arg1] "{$4}" (arg1),128 [arg1] "{$4}" (arg1),
...@@ -149,10 +146,10 @@ pub fn syscall7(...@@ -149,10 +146,10 @@ pub fn syscall7(
149) u32 {146) u32 {
150 return asm volatile (147 return asm volatile (
151 \\ syscall148 \\ syscall
152 \\ beq $7, $zero, 1f149 \\ beq $a3, $zero, 1f
153 \\ blez $2, 1f150 \\ blez $v0, 1f
154 \\ dsubu $2, $0, $2151 \\ dsubu $v0, $zero, $v0
155 \\ 1:152 \\1:
156 : [ret] "={$2}" (-> u32),153 : [ret] "={$2}" (-> u32),
157 : [number] "{$2}" (@intFromEnum(number)),154 : [number] "{$2}" (@intFromEnum(number)),
158 [arg1] "{$4}" (arg1),155 [arg1] "{$4}" (arg1),
...@@ -167,33 +164,33 @@ pub fn syscall7(...@@ -167,33 +164,33 @@ pub fn syscall7(
167164
168pub fn clone() callconv(.naked) u32 {165pub fn clone() callconv(.naked) u32 {
169 // __clone(func, stack, flags, arg, ptid, tls, ctid)166 // __clone(func, stack, flags, arg, ptid, tls, ctid)
170 // 3, 4, 5, 6, 7, 8, 9167 // a0, a1, a2, a3, a4, a5, a6
171 //168 //
172 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)169 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
173 // 2 4, 5, 6, 7, 8170 // v0 a0, a1, a2, a3, a4
174 asm volatile (171 asm volatile (
175 \\ # Save function pointer and argument pointer on new thread stack172 \\ # Save function pointer and argument pointer on new thread stack
176 \\ and $5, $5, -16173 \\ and $a1, $a1, -16
177 \\ dsubu $5, $5, 16174 \\ dsubu $a1, $a1, 16
178 \\ sd $4, 0($5)175 \\ sd $a0, 0($a1)
179 \\ sd $7, 8($5)176 \\ sd $a3, 8($a1)
177 \\
180 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)178 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
181 \\ move $4, $6179 \\ move $a0, $a2
182 \\ move $6, $8180 \\ move $a2, $a4
183 \\ move $7, $9181 \\ move $a3, $a5
184 \\ move $8, $10182 \\ move $a4, $a6
185 \\ li $2, 5055 # SYS_clone183 \\ li $v0, 5055 # SYS_clone
186 \\ syscall184 \\ syscall
187 \\ beq $7, $0, 1f185 \\ beq $a3, $zero, 1f
188 \\ nop186 \\ blez $v0, 2f
189 \\ jr $ra187 \\ dsubu $v0, $zero, $v0
190 \\ dsubu $2, $0, $2188 \\ b 2f
191 \\1:189 \\1:
192 \\ beq $2, $0, 1f190 \\ beq $v0, $zero, 3f
193 \\ nop191 \\2:
194 \\ jr $ra192 \\ jr $ra
195 \\ nop193 \\3:
196 \\1:
197 );194 );
198 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (195 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
199 \\ .cfi_undefined $ra196 \\ .cfi_undefined $ra
...@@ -202,12 +199,12 @@ pub fn clone() callconv(.naked) u32 {...@@ -202,12 +199,12 @@ pub fn clone() callconv(.naked) u32 {
202 \\ move $fp, $zero199 \\ move $fp, $zero
203 \\ move $ra, $zero200 \\ move $ra, $zero
204 \\201 \\
205 \\ ld $25, 0($sp)202 \\ ld $t9, 0($sp)
206 \\ ld $4, 8($sp)203 \\ ld $a0, 8($sp)
207 \\ jalr $25204 \\ jalr $t9
208 \\ nop205 \\
209 \\ move $4, $2206 \\ move $a0, $v0
210 \\ li $2, 5058 # SYS_exit207 \\ li $v0, 5058 # SYS_exit
211 \\ syscall208 \\ syscall
212 );209 );
213}210}
lib/std/pie.zig+3-2
...@@ -121,8 +121,9 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {...@@ -121,8 +121,9 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
121 \\ .hidden _DYNAMIC121 \\ .hidden _DYNAMIC
122 \\ bal 1f122 \\ bal 1f
123 \\ .gpword _DYNAMIC123 \\ .gpword _DYNAMIC
124 \\ 1:124 \\1:
125 \\ lw %[ret], 0($ra)125 \\ lw %[ret], 0($ra)
126 \\ nop
126 \\ addu %[ret], %[ret], $gp127 \\ addu %[ret], %[ret], $gp
127 : [ret] "=r" (-> [*]const elf.Dyn),128 : [ret] "=r" (-> [*]const elf.Dyn),
128 :129 :
...@@ -133,7 +134,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {...@@ -133,7 +134,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
133 \\ .balign 8134 \\ .balign 8
134 \\ bal 1f135 \\ bal 1f
135 \\ .gpdword _DYNAMIC136 \\ .gpdword _DYNAMIC
136 \\ 1:137 \\1:
137 \\ ld %[ret], 0($ra)138 \\ ld %[ret], 0($ra)
138 \\ daddu %[ret], %[ret], $gp139 \\ daddu %[ret], %[ret], $gp
139 : [ret] "=r" (-> [*]const elf.Dyn),140 : [ret] "=r" (-> [*]const elf.Dyn),
lib/std/start.zig+14-12
...@@ -325,24 +325,26 @@ fn _start() callconv(.naked) noreturn {...@@ -325,24 +325,26 @@ fn _start() callconv(.naked) noreturn {
325 \\ jsr (%%pc, %%a0)325 \\ jsr (%%pc, %%a0)
326 ,326 ,
327 .mips, .mipsel =>327 .mips, .mipsel =>
328 \\ move $fp, $0328 \\ move $fp, $zero
329 \\ bal 1f329 \\ bal 1f
330 \\ .gpword .330 \\ .gpword .
331 \\ .gpword %[posixCallMainAndExit]331 \\ .gpword %[posixCallMainAndExit]
332 \\ 1:332 \\1:
333 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.333 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
334 \\ lw $gp, 0($ra)334 \\ lw $gp, 0($ra)
335 \\ nop
335 \\ subu $gp, $ra, $gp336 \\ subu $gp, $ra, $gp
336 \\ lw $25, 4($ra)337 \\ lw $t9, 4($ra)
337 \\ addu $25, $25, $gp338 \\ nop
338 \\ move $ra, $0339 \\ addu $t9, $t9, $gp
340 \\ move $ra, $zero
339 \\ move $a0, $sp341 \\ move $a0, $sp
340 \\ and $sp, -8342 \\ and $sp, -8
341 \\ subu $sp, $sp, 16343 \\ subu $sp, $sp, 16
342 \\ jalr $25344 \\ jalr $t9
343 ,345 ,
344 .mips64, .mips64el =>346 .mips64, .mips64el =>
345 \\ move $fp, $0347 \\ move $fp, $zero
346 // This is needed because early MIPS versions don't support misaligned loads. Without348 // This is needed because early MIPS versions don't support misaligned loads. Without
347 // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would349 // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would
348 // cause the two doublewords to be aligned to 4 bytes instead of 8.350 // cause the two doublewords to be aligned to 4 bytes instead of 8.
...@@ -350,17 +352,17 @@ fn _start() callconv(.naked) noreturn {...@@ -350,17 +352,17 @@ fn _start() callconv(.naked) noreturn {
350 \\ bal 1f352 \\ bal 1f
351 \\ .gpdword .353 \\ .gpdword .
352 \\ .gpdword %[posixCallMainAndExit]354 \\ .gpdword %[posixCallMainAndExit]
353 \\ 1:355 \\1:
354 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.356 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
355 \\ ld $gp, 0($ra)357 \\ ld $gp, 0($ra)
356 \\ dsubu $gp, $ra, $gp358 \\ dsubu $gp, $ra, $gp
357 \\ ld $25, 8($ra)359 \\ ld $t9, 8($ra)
358 \\ daddu $25, $25, $gp360 \\ daddu $t9, $t9, $gp
359 \\ move $ra, $0361 \\ move $ra, $zero
360 \\ move $a0, $sp362 \\ move $a0, $sp
361 \\ and $sp, -16363 \\ and $sp, -16
362 \\ dsubu $sp, $sp, 16364 \\ dsubu $sp, $sp, 16
363 \\ jalr $25365 \\ jalr $t9
364 ,366 ,
365 .powerpc, .powerpcle =>367 .powerpc, .powerpcle =>
366 // Set up the initial stack frame, and clear the back chain pointer.368 // Set up the initial stack frame, and clear the back chain pointer.