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 #ifdef GOARCH_ppc64le
421 // Call the function stored in _cgo_sigaction using the GCC calling convention.
422 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
423 MOVD sig+0(FP), R3
424 MOVD new+8(FP), R4
425 MOVD old+16(FP), R5
426 MOVD _cgo_sigaction(SB), R12
427 MOVD R12, CTR // R12 should contain the function address
428 MOVD R1, R15 // Save R1
429 MOVD R2, 24(R1) // Save R2
430 SUB $48, R1 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
431 RLDICR $0, R1, $59, R1 // Align to 16 bytes for C code
432 BL (CTR)
433 XOR R0, R0, R0 // Clear R0 as Go expects
434 MOVD R15, R1 // Restore R1
435 MOVD 24(R1), R2 // Restore R2
436 MOVW R3, ret+24(FP) // Return result
437 RET
438 #endif
439
440 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
441 MOVW sig+8(FP), R3
442 MOVD info+16(FP), R4
443 MOVD ctx+24(FP), R5
444 MOVD fn+0(FP), R12
445 MOVD R12, CTR
446 BL (CTR)
447 MOVD 24(R1), R2
448 RET
449
450 #ifdef GOARCH_ppc64
451 // cgo isn't supported on ppc64, but we need to supply a cgoSigTramp function.
452 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
453 BR runtime·sigtramp(SB)
454 #endif
455
456 // Save callee-save registers in the case of signal forwarding.
457 // Same as on ARM64 https://golang.org/issue/31827 .
458 //
459 // Note, it is assumed this is always called indirectly (e.g via
460 // a function pointer) as R2 may not be preserved when calling this
461 // function. In those cases, the caller preserves their R2.
462 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
463 // This is called with ELF calling conventions. Convert to Go.
464 // Allocate space for argument storage to call runtime.sigtrampgo.
465 STACK_AND_SAVE_HOST_TO_GO_ABI(32)
466
467 // this might be called in external code context,
468 // where g is not set.
469 MOVBZ runtime·iscgo(SB), R6
470 CMP R6, $0
471 BEQ 2(PC)
472 BL runtime·load_g(SB)
473
474 // R3,R4,R5 already hold the arguments. Forward them on.
475 // TODO: Indirectly call runtime.sigtrampgo to avoid the linker's static NOSPLIT stack
476 // overflow detection. It thinks this might be called on a small Go stack, but this is only
477 // called from a larger pthread or sigaltstack stack. Can the checker be improved to not
478 // flag a direct call here?
479 MOVD $runtime·sigtrampgo<ABIInternal>(SB), R12
480 MOVD R12, CTR
481 BL (CTR)
482 // Restore R2 (TOC pointer) in the event it might be used later in this function.
483 // If this was not compiled as shared code, R2 is undefined, reloading it is harmless.
484 MOVD 24(R1), R2
485
486 UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
487 RET
488
489 #ifdef GOARCH_ppc64le
490 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
491 // The stack unwinder, presumably written in C, may not be able to
492 // handle Go frame correctly. So, this function is NOFRAME, and we
493 // save/restore LR manually, and obey ELFv2 calling conventions.
494 MOVD LR, R10
495
496 // We're coming from C code, initialize R0
497 MOVD $0, R0
498
499 // If no traceback function, do usual sigtramp.
500 MOVD runtime·cgoTraceback(SB), R6
501 CMP $0, R6
502 BEQ sigtramp
503
504 // If no traceback support function, which means that
505 // runtime/cgo was not linked in, do usual sigtramp.
506 MOVD _cgo_callers(SB), R6
507 CMP $0, R6
508 BEQ sigtramp
509
510 // Inspect the g in TLS without clobbering R30/R31 via runtime.load_g.
511 MOVD runtime·tls_g(SB), R9
512 MOVD 0(R9), R9
513
514 // Figure out if we are currently in a cgo call.
515 // If not, just do usual sigtramp.
516 // compared to ARM64 and others.
517 CMP $0, R9
518 BEQ sigtrampnog // g == nil
519
520 // g is not nil. Check further.
521 MOVD g_m(R9), R6
522 CMP $0, R6
523 BEQ sigtramp // g.m == nil
524 MOVW m_ncgo(R6), R7
525 CMPW $0, R7
526 BEQ sigtramp // g.m.ncgo = 0
527 MOVD m_curg(R6), R7
528 CMP $0, R7
529 BEQ sigtramp // g.m.curg == nil
530 MOVD g_syscallsp(R7), R7
531 CMP $0, R7
532 BEQ sigtramp // g.m.curg.syscallsp == 0
533 MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
534 CMP $0, R7
535 BEQ sigtramp // g.m.cgoCallers == nil
536 MOVW m_cgoCallersUse(R6), R8
537 CMPW $0, R8
538 BNE sigtramp // g.m.cgoCallersUse != 0
539
540 // Jump to a function in runtime/cgo.
541 // That function, written in C, will call the user's traceback
542 // function with proper unwind info, and will then call back here.
543 // The first three arguments, and the fifth, are already in registers.
544 // Set the two remaining arguments now.
545 MOVD runtime·cgoTraceback(SB), R6
546 MOVD $runtime·sigtramp(SB), R8
547 MOVD _cgo_callers(SB), R12
548 MOVD R12, CTR
549 MOVD R10, LR // restore LR
550 JMP (CTR)
551
552 sigtramp:
553 MOVD R10, LR // restore LR
554 JMP runtime·sigtramp(SB)
555
556 sigtrampnog:
557 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
558 // stack trace.
559 CMPW R3, $27 // 27 == SIGPROF
560 BNE sigtramp
561
562 // Lock sigprofCallersUse (cas from 0 to 1).
563 MOVW $1, R7
564 MOVD $runtime·sigprofCallersUse(SB), R8
565 SYNC
566 LWAR (R8), R6
567 CMPW $0, R6
568 BNE sigtramp
569 STWCCC R7, (R8)
570 BNE -4(PC)
571 ISYNC
572
573 // Jump to the traceback function in runtime/cgo.
574 // It will call back to sigprofNonGo, which will ignore the
575 // arguments passed in registers.
576 // First three arguments to traceback function are in registers already.
577 MOVD runtime·cgoTraceback(SB), R6
578 MOVD $runtime·sigprofCallers(SB), R7
579 MOVD $runtime·sigprofNonGoWrapper<>(SB), R8
580 MOVD _cgo_callers(SB), R12
581 MOVD R12, CTR
582 MOVD R10, LR // restore LR
583 JMP (CTR)
584 #endif
585
586 // Used by cgoSigtramp to inspect without clobbering R30/R31 via runtime.load_g.
587 GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
588
589 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
590 // This is called from C code. Callee save registers must be saved.
591 // R3,R4,R5 hold arguments, and allocate argument space to call sigprofNonGo.
592 STACK_AND_SAVE_HOST_TO_GO_ABI(32)
593
594 CALL runtime·sigprofNonGo<ABIInternal>(SB)
595
596 UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
597 RET
598
599 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
600 MOVD addr+0(FP), R3
601 MOVD n+8(FP), R4
602 MOVW prot+16(FP), R5
603 MOVW flags+20(FP), R6
604 MOVW fd+24(FP), R7
605 MOVW off+28(FP), R8
606
607 SYSCALL $SYS_mmap
608 BVC ok
609 MOVD $0, p+32(FP)
610 MOVD R3, err+40(FP)
611 RET
612 ok:
613 MOVD R3, p+32(FP)
614 MOVD $0, err+40(FP)
615 RET
616
617 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
618 MOVD addr+0(FP), R3
619 MOVD n+8(FP), R4
620 SYSCALL $SYS_munmap
621 BVC 2(PC)
622 MOVD R0, 0xf0(R0)
623 RET
624
625 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
626 MOVD addr+0(FP), R3
627 MOVD n+8(FP), R4
628 MOVW flags+16(FP), R5
629 SYSCALL $SYS_madvise
630 MOVW R3, ret+24(FP)
631 RET
632
633 // int64 futex(int32 *uaddr, int32 op, int32 val,
634 // struct timespec *timeout, int32 *uaddr2, int32 val2);
635 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
636 MOVD addr+0(FP), R3
637 MOVW op+8(FP), R4
638 MOVW val+12(FP), R5
639 MOVD ts+16(FP), R6
640 MOVD addr2+24(FP), R7
641 MOVW val3+32(FP), R8
642 SYSCALL $SYS_futex
643 BVC 2(PC)
644 NEG R3 // caller expects negative errno
645 MOVW R3, ret+40(FP)
646 RET
647
648 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
649 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
650 MOVW flags+0(FP), R3
651 MOVD stk+8(FP), R4
652
653 // Copy mp, gp, fn off parent stack for use by child.
654 // Careful: Linux system call clobbers ???.
655 MOVD mp+16(FP), R7
656 MOVD gp+24(FP), R8
657 MOVD fn+32(FP), R12
658
659 MOVD R7, -8(R4)
660 MOVD R8, -16(R4)
661 MOVD R12, -24(R4)
662 MOVD $1234, R7
663 MOVD R7, -32(R4)
664
665 SYSCALL $SYS_clone
666 BVC 2(PC)
667 NEG R3 // caller expects negative errno
668
669 // In parent, return.
670 CMP R3, $0
671 BEQ 3(PC)
672 MOVW R3, ret+40(FP)
673 RET
674
675 // In child, on new stack.
676 // initialize essential registers
677 BL runtime·reginit(SB)
678 MOVD -32(R1), R7
679 CMP R7, $1234
680 BEQ 2(PC)
681 MOVD R0, 0(R0)
682
683 // Initialize m->procid to Linux tid
684 SYSCALL $SYS_gettid
685
686 MOVD -24(R1), R12 // fn
687 MOVD -16(R1), R8 // g
688 MOVD -8(R1), R7 // m
689
690 CMP R7, $0
691 BEQ nog
692 CMP R8, $0
693 BEQ nog
694
695 MOVD R3, m_procid(R7)
696
697 // TODO: setup TLS.
698
699 // In child, set up new stack
700 MOVD R7, g_m(R8)
701 MOVD R8, g
702 //CALL runtime·stackcheck(SB)
703
704 nog:
705 // Call fn
706 MOVD R12, CTR
707 BL (CTR)
708
709 // It shouldn't return. If it does, exit that thread.
710 MOVW $111, R3
711 SYSCALL $SYS_exit
712 BR -2(PC) // keep exiting
713
714 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
715 MOVD new+0(FP), R3
716 MOVD old+8(FP), R4
717 SYSCALL $SYS_sigaltstack
718 BVC 2(PC)
719 MOVD R0, 0xf0(R0) // crash
720 RET
721
722 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
723 SYSCALL $SYS_sched_yield
724 RET
725
726 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
727 MOVD pid+0(FP), R3
728 MOVD len+8(FP), R4
729 MOVD buf+16(FP), R5
730 SYSCALL $SYS_sched_getaffinity
731 BVC 2(PC)
732 NEG R3 // caller expects negative errno
733 MOVW R3, ret+24(FP)
734 RET
735
736 // func sbrk0() uintptr
737 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
738 // Implemented as brk(NULL).
739 MOVD $0, R3
740 SYSCALL $SYS_brk
741 MOVD R3, ret+0(FP)
742 RET
743
744 TEXT runtime·access(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 TEXT runtime·connect(SB),$0-28
750 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
751 MOVW R0, ret+24(FP) // for vet
752 RET
753
754 TEXT runtime·socket(SB),$0-20
755 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
756 MOVW R0, ret+16(FP) // for vet
757 RET
758
759 // func vgetrandom1(buf *byte, length uintptr, flags uint32, state uintptr, stateSize uintptr) int
760 TEXT runtime·vgetrandom1<ABIInternal>(SB),NOSPLIT,$16-48
761 MOVD R1, R15
762
763 MOVD runtime·vdsoGetrandomSym(SB), R12
764 MOVD R12, CTR
765 MOVD g_m(g), R21
766
767 MOVD m_vdsoPC(R21), R22
768 MOVD R22, 32(R1)
769 MOVD m_vdsoSP(R21), R22
770 MOVD R22, 40(R1)
771 MOVD LR, m_vdsoPC(R21)
772 MOVD $buf-FIXED_FRAME(FP), R22
773 MOVD R22, m_vdsoSP(R21)
774
775 RLDICR $0, R1, $59, R1
776
777 MOVBZ runtime·iscgo(SB), R22
778 CMP R22, $0
779 BNE nosaveg
780 MOVD m_gsignal(R21), R22
781 CMP R22, $0
782 BEQ nosaveg
783 CMP R22, g
784 BEQ nosaveg
785 MOVD (g_stack+stack_lo)(R22), R22
786 MOVD g, (R22)
787
788 BL (CTR)
789
790 MOVD $0, (R22)
791 JMP restore
792
793 nosaveg:
794 BL (CTR)
795
796 restore:
797 MOVD $0, R0
798 MOVD R15, R1
799 MOVD 40(R1), R22
800 MOVD R22, m_vdsoSP(R21)
801 MOVD 32(R1), R22
802 MOVD R22, m_vdsoPC(R21)
803
804 BVC out
805 NEG R3, R3
806 out:
807 RET
808
View as plain text