Text file
src/runtime/sys_linux_ppc64x.s
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build linux && (ppc64 || ppc64le)
6
7 //
8 // System calls and other sys.stuff for ppc64, Linux
9 //
10
11 #include "go_asm.h"
12 #include "go_tls.h"
13 #include "textflag.h"
14 #include "asm_ppc64x.h"
15 #include "cgo/abi_ppc64x.h"
16
17 #define SYS_exit 1
18 #define SYS_read 3
19 #define SYS_write 4
20 #define SYS_open 5
21 #define SYS_close 6
22 #define SYS_getpid 20
23 #define SYS_kill 37
24 #define SYS_brk 45
25 #define SYS_mmap 90
26 #define SYS_munmap 91
27 #define SYS_setitimer 104
28 #define SYS_clone 120
29 #define SYS_sched_yield 158
30 #define SYS_nanosleep 162
31 #define SYS_rt_sigreturn 172
32 #define SYS_rt_sigaction 173
33 #define SYS_rt_sigprocmask 174
34 #define SYS_sigaltstack 185
35 #define SYS_madvise 205
36 #define SYS_mincore 206
37 #define SYS_gettid 207
38 #define SYS_futex 221
39 #define SYS_sched_getaffinity 223
40 #define SYS_exit_group 234
41 #define SYS_timer_create 240
42 #define SYS_timer_settime 241
43 #define SYS_timer_delete 244
44 #define SYS_clock_gettime 246
45 #define SYS_tgkill 250
46 #define SYS_pipe2 317
47
48 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
49 MOVW code+0(FP), R3
50 SYSCALL $SYS_exit_group
51 RET
52
53 // func exitThread(wait *atomic.Uint32)
54 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
55 MOVD wait+0(FP), R1
56 // We're done using the stack.
57 MOVW $0, R2
58 SYNC
59 MOVW R2, (R1)
60 MOVW $0, R3 // exit code
61 SYSCALL $SYS_exit
62 JMP 0(PC)
63
64 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
65 MOVD name+0(FP), R3
66 MOVW mode+8(FP), R4
67 MOVW perm+12(FP), R5
68 SYSCALL $SYS_open
69 BVC 2(PC)
70 MOVW $-1, R3
71 MOVW R3, ret+16(FP)
72 RET
73
74 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
75 MOVW fd+0(FP), R3
76 SYSCALL $SYS_close
77 BVC 2(PC)
78 MOVW $-1, R3
79 MOVW R3, ret+8(FP)
80 RET
81
82 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
83 MOVD fd+0(FP), R3
84 MOVD p+8(FP), R4
85 MOVW n+16(FP), R5
86 SYSCALL $SYS_write
87 BVC 2(PC)
88 NEG R3 // caller expects negative errno
89 MOVW R3, ret+24(FP)
90 RET
91
92 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
93 MOVW fd+0(FP), R3
94 MOVD p+8(FP), R4
95 MOVW n+16(FP), R5
96 SYSCALL $SYS_read
97 BVC 2(PC)
98 NEG R3 // caller expects negative errno
99 MOVW R3, ret+24(FP)
100 RET
101
102 // func pipe2(flags int32) (r, w int32, errno int32)
103 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
104 ADD $FIXED_FRAME+8, R1, R3
105 MOVW flags+0(FP), R4
106 SYSCALL $SYS_pipe2
107 MOVW R3, errno+16(FP)
108 RET
109
110 // func usleep(usec uint32)
111 TEXT runtime·usleep(SB),NOSPLIT,$16-4
112 MOVW usec+0(FP), R3
113
114 // Use magic constant 0x8637bd06 and shift right 51
115 // to perform usec/1000000.
116 MOVD $0x8637bd06, R4
117 MULLD R3, R4, R4 // Convert usec to S.
118 SRD $51, R4, R4
119 MOVD R4, 8(R1) // Store to tv_sec
120
121 MOVD $1000000, R5
122 MULLW R4, R5, R5 // Convert tv_sec back into uS
123 SUB R5, R3, R5 // Compute remainder uS.
124 MULLD $1000, R5, R5 // Convert to nsec
125 MOVD R5, 16(R1) // Store to tv_nsec
126
127 // nanosleep(&ts, 0)
128 ADD $8, R1, R3
129 MOVW $0, R4
130 SYSCALL $SYS_nanosleep
131 RET
132
133 TEXT runtime·gettid(SB),NOSPLIT,$0-4
134 SYSCALL $SYS_gettid
135 MOVW R3, ret+0(FP)
136 RET
137
138 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
139 SYSCALL $SYS_getpid
140 MOVW R3, R14
141 SYSCALL $SYS_gettid
142 MOVW R3, R4 // arg 2 tid
143 MOVW R14, R3 // arg 1 pid
144 MOVW sig+0(FP), R5 // arg 3
145 SYSCALL $SYS_tgkill
146 RET
147
148 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
149 SYSCALL $SYS_getpid
150 MOVW R3, R3 // arg 1 pid
151 MOVW sig+0(FP), R4 // arg 2
152 SYSCALL $SYS_kill
153 RET
154
155 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
156 SYSCALL $SYS_getpid
157 MOVD R3, ret+0(FP)
158 RET
159
160 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
161 MOVD tgid+0(FP), R3
162 MOVD tid+8(FP), R4
163 MOVD sig+16(FP), R5
164 SYSCALL $SYS_tgkill
165 RET
166
167 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
168 MOVW mode+0(FP), R3
169 MOVD new+8(FP), R4
170 MOVD old+16(FP), R5
171 SYSCALL $SYS_setitimer
172 RET
173
174 TEXT runtime·timer_create(SB),NOSPLIT,$0-28
175 MOVW clockid+0(FP), R3
176 MOVD sevp+8(FP), R4
177 MOVD timerid+16(FP), R5
178 SYSCALL $SYS_timer_create
179 MOVW R3, ret+24(FP)
180 RET
181
182 TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
183 MOVW timerid+0(FP), R3
184 MOVW flags+4(FP), R4
185 MOVD new+8(FP), R5
186 MOVD old+16(FP), R6
187 SYSCALL $SYS_timer_settime
188 MOVW R3, ret+24(FP)
189 RET
190
191 TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
192 MOVW timerid+0(FP), R3
193 SYSCALL $SYS_timer_delete
194 MOVW R3, ret+8(FP)
195 RET
196
197 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
198 MOVD addr+0(FP), R3
199 MOVD n+8(FP), R4
200 MOVD dst+16(FP), R5
201 SYSCALL $SYS_mincore
202 NEG R3 // caller expects negative errno
203 MOVW R3, ret+24(FP)
204 RET
205
206 // func walltime() (sec int64, nsec int32)
207 TEXT runtime·walltime(SB),NOSPLIT,$16-12
208 MOVD R1, R15 // R15 is unchanged by C code
209 MOVD g_m(g), R21 // R21 = m
210
211 MOVD $0, R3 // CLOCK_REALTIME
212
213 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
214 CMP R12, $0
215 BEQ fallback
216
217 // Set vdsoPC and vdsoSP for SIGPROF traceback.
218 // Save the old values on stack and restore them on exit,
219 // so this function is reentrant.
220 MOVD m_vdsoPC(R21), R4
221 MOVD m_vdsoSP(R21), R5
222 MOVD R4, 32(R1)
223 MOVD R5, 40(R1)
224
225 MOVD LR, R14
226 MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP
227 MOVD R14, m_vdsoPC(R21)
228 MOVD R5, m_vdsoSP(R21)
229
230 MOVD m_curg(R21), R6
231 CMP g, R6
232 BNE noswitch
233
234 MOVD m_g0(R21), R7
235 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
236
237 noswitch:
238 SUB $16, R1 // Space for results
239 RLDICR $0, R1, $59, R1 // Align for C code
240 MOVD R12, CTR
241 MOVD R1, R4
242
243 // Store g on gsignal's stack, so if we receive a signal
244 // during VDSO code we can find the g.
245 // If we don't have a signal stack, we won't receive signal,
246 // so don't bother saving g.
247 // When using cgo, we already saved g on TLS, also don't save
248 // g here.
249 // Also don't save g if we are already on the signal stack.
250 // We won't get a nested signal.
251 MOVBZ runtime·iscgo(SB), R22
252 CMP R22, $0
253 BNE nosaveg
254 MOVD m_gsignal(R21), R22 // g.m.gsignal
255 CMP R22, $0
256 BEQ nosaveg
257
258 CMP g, R22
259 BEQ nosaveg
260 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
261 MOVD g, (R22)
262
263 BL (CTR) // Call from VDSO
264
265 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
266
267 JMP finish
268
269 nosaveg:
270 BL (CTR) // Call from VDSO
271
272 finish:
273 MOVD $0, R0 // Restore R0
274 MOVD 0(R1), R3 // sec
275 MOVD 8(R1), R5 // nsec
276 MOVD R15, R1 // Restore SP
277
278 // Restore vdsoPC, vdsoSP
279 // We don't worry about being signaled between the two stores.
280 // If we are not in a signal handler, we'll restore vdsoSP to 0,
281 // and no one will care about vdsoPC. If we are in a signal handler,
282 // we cannot receive another signal.
283 MOVD 40(R1), R6
284 MOVD R6, m_vdsoSP(R21)
285 MOVD 32(R1), R6
286 MOVD R6, m_vdsoPC(R21)
287
288 return:
289 MOVD R3, sec+0(FP)
290 MOVW R5, nsec+8(FP)
291 RET
292
293 // Syscall fallback
294 fallback:
295 ADD $32, R1, R4
296 SYSCALL $SYS_clock_gettime
297 MOVD 32(R1), R3
298 MOVD 40(R1), R5
299 JMP return
300
301 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
302 MOVD $1, R3 // CLOCK_MONOTONIC
303
304 MOVD R1, R15 // R15 is unchanged by C code
305 MOVD g_m(g), R21 // R21 = m
306
307 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
308 CMP R12, $0
309 BEQ fallback
310
311 // Set vdsoPC and vdsoSP for SIGPROF traceback.
312 // Save the old values on stack and restore them on exit,
313 // so this function is reentrant.
314 MOVD m_vdsoPC(R21), R4
315 MOVD m_vdsoSP(R21), R5
316 MOVD R4, 32(R1)
317 MOVD R5, 40(R1)
318
319 MOVD LR, R14 // R14 is unchanged by C code
320 MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP
321 MOVD R14, m_vdsoPC(R21)
322 MOVD R5, m_vdsoSP(R21)
323
324 MOVD m_curg(R21), R6
325 CMP g, R6
326 BNE noswitch
327
328 MOVD m_g0(R21), R7
329 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
330
331 noswitch:
332 SUB $16, R1 // Space for results
333 RLDICR $0, R1, $59, R1 // Align for C code
334 MOVD R12, CTR
335 MOVD R1, R4
336
337 // Store g on gsignal's stack, so if we receive a signal
338 // during VDSO code we can find the g.
339 // If we don't have a signal stack, we won't receive signal,
340 // so don't bother saving g.
341 // When using cgo, we already saved g on TLS, also don't save
342 // g here.
343 // Also don't save g if we are already on the signal stack.
344 // We won't get a nested signal.
345 MOVBZ runtime·iscgo(SB), R22
346 CMP R22, $0
347 BNE nosaveg
348 MOVD m_gsignal(R21), R22 // g.m.gsignal
349 CMP R22, $0
350 BEQ nosaveg
351
352 CMP g, R22
353 BEQ nosaveg
354 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
355 MOVD g, (R22)
356
357 BL (CTR) // Call from VDSO
358
359 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
360
361 JMP finish
362
363 nosaveg:
364 BL (CTR) // Call from VDSO
365
366 finish:
367 MOVD $0, R0 // Restore R0
368 MOVD 0(R1), R3 // sec
369 MOVD 8(R1), R5 // nsec
370 MOVD R15, R1 // Restore SP
371
372 // Restore vdsoPC, vdsoSP
373 // We don't worry about being signaled between the two stores.
374 // If we are not in a signal handler, we'll restore vdsoSP to 0,
375 // and no one will care about vdsoPC. If we are in a signal handler,
376 // we cannot receive another signal.
377 MOVD 40(R1), R6
378 MOVD R6, m_vdsoSP(R21)
379 MOVD 32(R1), R6
380 MOVD R6, m_vdsoPC(R21)
381
382 return:
383 // sec is in R3, nsec in R5
384 // return nsec in R3
385 MOVD $1000000000, R4
386 MULLD R4, R3
387 ADD R5, R3
388 MOVD R3, ret+0(FP)
389 RET
390
391 // Syscall fallback
392 fallback:
393 ADD $32, R1, R4
394 SYSCALL $SYS_clock_gettime
395 MOVD 32(R1), R3
396 MOVD 40(R1), R5
397 JMP return
398
399 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
400 MOVW how+0(FP), R3
401 MOVD new+8(FP), R4
402 MOVD old+16(FP), R5
403 MOVW size+24(FP), R6
404 SYSCALL $SYS_rt_sigprocmask
405 BVC 2(PC)
406 MOVD R0, 0xf0(R0) // crash
407 RET
408
409 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
410 MOVD sig+0(FP), R3
411 MOVD new+8(FP), R4
412 MOVD old+16(FP), R5
413 MOVD size+24(FP), R6
414 SYSCALL $SYS_rt_sigaction
415 BVC 2(PC)
416 NEG R3 // caller expects negative errno
417 MOVW R3, ret+32(FP)
418 RET
419
420 // Call the function stored in _cgo_sigaction using the GCC calling convention.
421 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
422 MOVD sig+0(FP), R3
423 MOVD new+8(FP), R4
424 MOVD old+16(FP), R5
425 MOVD _cgo_sigaction(SB), R12
426 MOVD R12, CTR // R12 should contain the function address
427 MOVD R1, R15 // Save R1
428 MOVD R2, 24(R1) // Save R2
429 SUB $48, R1 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
430 RLDICR $0, R1, $59, R1 // Align to 16 bytes for C code
431 BL (CTR)
432 XOR R0, R0, R0 // Clear R0 as Go expects
433 MOVD R15, R1 // Restore R1
434 MOVD 24(R1), R2 // Restore R2
435 MOVW R3, ret+24(FP) // Return result
436 RET
437
438 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
439 MOVW sig+8(FP), R3
440 MOVD info+16(FP), R4
441 MOVD ctx+24(FP), R5
442 MOVD fn+0(FP), R12
443 MOVD R12, CTR
444 BL (CTR)
445 MOVD 24(R1), R2
446 RET
447
448 // Save callee-save registers in the case of signal forwarding.
449 // Same as on ARM64 https://golang.org/issue/31827 .
450 //
451 // Note, it is assumed this is always called indirectly (e.g via
452 // a function pointer) as R2 may not be preserved when calling this
453 // function. In those cases, the caller preserves their R2.
454 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
455 // This is called with ELF calling conventions. Convert to Go.
456 // Allocate space for argument storage to call runtime.sigtrampgo.
457 STACK_AND_SAVE_HOST_TO_GO_ABI(32)
458
459 // this might be called in external code context,
460 // where g is not set.
461 MOVBZ runtime·iscgo(SB), R6
462 CMP R6, $0
463 BEQ 2(PC)
464 BL runtime·load_g(SB)
465
466 // R3,R4,R5 already hold the arguments. Forward them on.
467 // TODO: Indirectly call runtime.sigtrampgo to avoid the linker's static NOSPLIT stack
468 // overflow detection. It thinks this might be called on a small Go stack, but this is only
469 // called from a larger pthread or sigaltstack stack. Can the checker be improved to not
470 // flag a direct call here?
471 MOVD $runtime·sigtrampgo<ABIInternal>(SB), R12
472 MOVD R12, CTR
473 BL (CTR)
474 // Restore R2 (TOC pointer) in the event it might be used later in this function.
475 // If this was not compiled as shared code, R2 is undefined, reloading it is harmless.
476 MOVD 24(R1), R2
477
478 UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
479 RET
480
481 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
482 // The stack unwinder, presumably written in C, may not be able to
483 // handle Go frame correctly. So, this function is NOFRAME, and we
484 // save/restore LR manually, and obey ELFv2 calling conventions.
485 MOVD LR, R10
486
487 // We're coming from C code, initialize R0
488 MOVD $0, R0
489
490 // If no traceback function, do usual sigtramp.
491 MOVD runtime·cgoTraceback(SB), R6
492 CMP $0, R6
493 BEQ sigtramp
494
495 // If no traceback support function, which means that
496 // runtime/cgo was not linked in, do usual sigtramp.
497 MOVD _cgo_callers(SB), R6
498 CMP $0, R6
499 BEQ sigtramp
500
501 // Inspect the g in TLS without clobbering R30/R31 via runtime.load_g.
502 MOVD runtime·tls_g(SB), R9
503 MOVD 0(R9), R9
504
505 // Figure out if we are currently in a cgo call.
506 // If not, just do usual sigtramp.
507 // compared to ARM64 and others.
508 CMP $0, R9
509 BEQ sigtrampnog // g == nil
510
511 // g is not nil. Check further.
512 MOVD g_m(R9), R6
513 CMP $0, R6
514 BEQ sigtramp // g.m == nil
515 MOVW m_ncgo(R6), R7
516 CMPW $0, R7
517 BEQ sigtramp // g.m.ncgo = 0
518 MOVD m_curg(R6), R7
519 CMP $0, R7
520 BEQ sigtramp // g.m.curg == nil
521 MOVD g_syscallsp(R7), R7
522 CMP $0, R7
523 BEQ sigtramp // g.m.curg.syscallsp == 0
524 MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
525 CMP $0, R7
526 BEQ sigtramp // g.m.cgoCallers == nil
527 MOVW m_cgoCallersUse(R6), R8
528 CMPW $0, R8
529 BNE sigtramp // g.m.cgoCallersUse != 0
530
531 // Jump to a function in runtime/cgo.
532 // That function, written in C, will call the user's traceback
533 // function with proper unwind info, and will then call back here.
534 // The first three arguments, and the fifth, are already in registers.
535 // Set the two remaining arguments now.
536 MOVD runtime·cgoTraceback(SB), R6
537 MOVD $runtime·sigtramp(SB), R8
538 MOVD _cgo_callers(SB), R12
539 MOVD R12, CTR
540 MOVD R10, LR // restore LR
541 JMP (CTR)
542
543 sigtramp:
544 MOVD R10, LR // restore LR
545 JMP runtime·sigtramp(SB)
546
547 sigtrampnog:
548 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
549 // stack trace.
550 CMPW R3, $27 // 27 == SIGPROF
551 BNE sigtramp
552
553 // Lock sigprofCallersUse (cas from 0 to 1).
554 MOVW $1, R7
555 MOVD $runtime·sigprofCallersUse(SB), R8
556 SYNC
557 LWAR (R8), R6
558 CMPW $0, R6
559 BNE sigtramp
560 STWCCC R7, (R8)
561 BNE -4(PC)
562 ISYNC
563
564 // Jump to the traceback function in runtime/cgo.
565 // It will call back to sigprofNonGo, which will ignore the
566 // arguments passed in registers.
567 // First three arguments to traceback function are in registers already.
568 MOVD runtime·cgoTraceback(SB), R6
569 MOVD $runtime·sigprofCallers(SB), R7
570 MOVD $runtime·sigprofNonGoWrapper<>(SB), R8
571 MOVD _cgo_callers(SB), R12
572 MOVD R12, CTR
573 MOVD R10, LR // restore LR
574 JMP (CTR)
575
576 // Used by cgoSigtramp to inspect without clobbering R30/R31 via runtime.load_g.
577 GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
578
579 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
580 // This is called from C code. Callee save registers must be saved.
581 // R3,R4,R5 hold arguments, and allocate argument space to call sigprofNonGo.
582 STACK_AND_SAVE_HOST_TO_GO_ABI(32)
583
584 CALL runtime·sigprofNonGo<ABIInternal>(SB)
585
586 UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
587 RET
588
589 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
590 MOVD addr+0(FP), R3
591 MOVD n+8(FP), R4
592 MOVW prot+16(FP), R5
593 MOVW flags+20(FP), R6
594 MOVW fd+24(FP), R7
595 MOVW off+28(FP), R8
596
597 SYSCALL $SYS_mmap
598 BVC ok
599 MOVD $0, p+32(FP)
600 MOVD R3, err+40(FP)
601 RET
602 ok:
603 MOVD R3, p+32(FP)
604 MOVD $0, err+40(FP)
605 RET
606
607 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
608 MOVD addr+0(FP), R3
609 MOVD n+8(FP), R4
610 SYSCALL $SYS_munmap
611 BVC 2(PC)
612 MOVD R0, 0xf0(R0)
613 RET
614
615 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
616 MOVD addr+0(FP), R3
617 MOVD n+8(FP), R4
618 MOVW flags+16(FP), R5
619 SYSCALL $SYS_madvise
620 MOVW R3, ret+24(FP)
621 RET
622
623 // int64 futex(int32 *uaddr, int32 op, int32 val,
624 // struct timespec *timeout, int32 *uaddr2, int32 val2);
625 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
626 MOVD addr+0(FP), R3
627 MOVW op+8(FP), R4
628 MOVW val+12(FP), R5
629 MOVD ts+16(FP), R6
630 MOVD addr2+24(FP), R7
631 MOVW val3+32(FP), R8
632 SYSCALL $SYS_futex
633 BVC 2(PC)
634 NEG R3 // caller expects negative errno
635 MOVW R3, ret+40(FP)
636 RET
637
638 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
639 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
640 MOVW flags+0(FP), R3
641 MOVD stk+8(FP), R4
642
643 // Copy mp, gp, fn off parent stack for use by child.
644 // Careful: Linux system call clobbers ???.
645 MOVD mp+16(FP), R7
646 MOVD gp+24(FP), R8
647 MOVD fn+32(FP), R12
648
649 MOVD R7, -8(R4)
650 MOVD R8, -16(R4)
651 MOVD R12, -24(R4)
652 MOVD $1234, R7
653 MOVD R7, -32(R4)
654
655 SYSCALL $SYS_clone
656 BVC 2(PC)
657 NEG R3 // caller expects negative errno
658
659 // In parent, return.
660 CMP R3, $0
661 BEQ 3(PC)
662 MOVW R3, ret+40(FP)
663 RET
664
665 // In child, on new stack.
666 // initialize essential registers
667 BL runtime·reginit(SB)
668 MOVD -32(R1), R7
669 CMP R7, $1234
670 BEQ 2(PC)
671 MOVD R0, 0(R0)
672
673 // Initialize m->procid to Linux tid
674 SYSCALL $SYS_gettid
675
676 MOVD -24(R1), R12 // fn
677 MOVD -16(R1), R8 // g
678 MOVD -8(R1), R7 // m
679
680 CMP R7, $0
681 BEQ nog
682 CMP R8, $0
683 BEQ nog
684
685 MOVD R3, m_procid(R7)
686
687 // TODO: setup TLS.
688
689 // In child, set up new stack
690 MOVD R7, g_m(R8)
691 MOVD R8, g
692 //CALL runtime·stackcheck(SB)
693
694 nog:
695 // Call fn
696 MOVD R12, CTR
697 BL (CTR)
698
699 // It shouldn't return. If it does, exit that thread.
700 MOVW $111, R3
701 SYSCALL $SYS_exit
702 BR -2(PC) // keep exiting
703
704 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
705 MOVD new+0(FP), R3
706 MOVD old+8(FP), R4
707 SYSCALL $SYS_sigaltstack
708 BVC 2(PC)
709 MOVD R0, 0xf0(R0) // crash
710 RET
711
712 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
713 SYSCALL $SYS_sched_yield
714 RET
715
716 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
717 MOVD pid+0(FP), R3
718 MOVD len+8(FP), R4
719 MOVD buf+16(FP), R5
720 SYSCALL $SYS_sched_getaffinity
721 BVC 2(PC)
722 NEG R3 // caller expects negative errno
723 MOVW R3, ret+24(FP)
724 RET
725
726 // func sbrk0() uintptr
727 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
728 // Implemented as brk(NULL).
729 MOVD $0, R3
730 SYSCALL $SYS_brk
731 MOVD R3, ret+0(FP)
732 RET
733
734 TEXT runtime·access(SB),$0-20
735 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
736 MOVW R0, ret+16(FP) // for vet
737 RET
738
739 TEXT runtime·connect(SB),$0-28
740 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
741 MOVW R0, ret+24(FP) // for vet
742 RET
743
744 TEXT runtime·socket(SB),$0-20
745 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
746 MOVW R0, ret+16(FP) // for vet
747 RET
748
749 // func vgetrandom1(buf *byte, length uintptr, flags uint32, state uintptr, stateSize uintptr) int
750 TEXT runtime·vgetrandom1<ABIInternal>(SB),NOSPLIT,$16-48
751 MOVD R1, R15
752
753 MOVD runtime·vdsoGetrandomSym(SB), R12
754 MOVD R12, CTR
755 MOVD g_m(g), R21
756
757 MOVD m_vdsoPC(R21), R22
758 MOVD R22, 32(R1)
759 MOVD m_vdsoSP(R21), R22
760 MOVD R22, 40(R1)
761 MOVD LR, m_vdsoPC(R21)
762 MOVD $buf-FIXED_FRAME(FP), R22
763 MOVD R22, m_vdsoSP(R21)
764
765 RLDICR $0, R1, $59, R1
766
767 MOVBZ runtime·iscgo(SB), R22
768 CMP R22, $0
769 BNE nosaveg
770 MOVD m_gsignal(R21), R22
771 CMP R22, $0
772 BEQ nosaveg
773 CMP R22, g
774 BEQ nosaveg
775 MOVD (g_stack+stack_lo)(R22), R22
776 MOVD g, (R22)
777
778 BL (CTR)
779
780 MOVD $0, (R22)
781 JMP restore
782
783 nosaveg:
784 BL (CTR)
785
786 restore:
787 MOVD $0, R0
788 MOVD R15, R1
789 MOVD 40(R1), R22
790 MOVD R22, m_vdsoSP(R21)
791 MOVD 32(R1), R22
792 MOVD R22, m_vdsoPC(R21)
793
794 BVC out
795 NEG R3, R3
796 out:
797 RET
798
View as plain text