Text file
src/runtime/sys_linux_ppc64x.s
Documentation: runtime
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 // +build linux
7 // +build ppc64 ppc64le
8
9 //
10 // System calls and other sys.stuff for ppc64, Linux
11 //
12
13 #include "go_asm.h"
14 #include "go_tls.h"
15 #include "textflag.h"
16 #include "asm_ppc64x.h"
17
18 #define SYS_exit 1
19 #define SYS_read 3
20 #define SYS_write 4
21 #define SYS_open 5
22 #define SYS_close 6
23 #define SYS_getpid 20
24 #define SYS_kill 37
25 #define SYS_pipe 42
26 #define SYS_brk 45
27 #define SYS_fcntl 55
28 #define SYS_mmap 90
29 #define SYS_munmap 91
30 #define SYS_setitimer 104
31 #define SYS_clone 120
32 #define SYS_sched_yield 158
33 #define SYS_nanosleep 162
34 #define SYS_rt_sigreturn 172
35 #define SYS_rt_sigaction 173
36 #define SYS_rt_sigprocmask 174
37 #define SYS_sigaltstack 185
38 #define SYS_madvise 205
39 #define SYS_mincore 206
40 #define SYS_gettid 207
41 #define SYS_futex 221
42 #define SYS_sched_getaffinity 223
43 #define SYS_exit_group 234
44 #define SYS_epoll_create 236
45 #define SYS_epoll_ctl 237
46 #define SYS_epoll_wait 238
47 #define SYS_clock_gettime 246
48 #define SYS_tgkill 250
49 #define SYS_epoll_create1 315
50 #define SYS_pipe2 317
51
52 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
53 MOVW code+0(FP), R3
54 SYSCALL $SYS_exit_group
55 RET
56
57 // func exitThread(wait *uint32)
58 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
59 MOVD wait+0(FP), R1
60 // We're done using the stack.
61 MOVW $0, R2
62 SYNC
63 MOVW R2, (R1)
64 MOVW $0, R3 // exit code
65 SYSCALL $SYS_exit
66 JMP 0(PC)
67
68 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
69 MOVD name+0(FP), R3
70 MOVW mode+8(FP), R4
71 MOVW perm+12(FP), R5
72 SYSCALL $SYS_open
73 BVC 2(PC)
74 MOVW $-1, R3
75 MOVW R3, ret+16(FP)
76 RET
77
78 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
79 MOVW fd+0(FP), R3
80 SYSCALL $SYS_close
81 BVC 2(PC)
82 MOVW $-1, R3
83 MOVW R3, ret+8(FP)
84 RET
85
86 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
87 MOVD fd+0(FP), R3
88 MOVD p+8(FP), R4
89 MOVW n+16(FP), R5
90 SYSCALL $SYS_write
91 BVC 2(PC)
92 NEG R3 // caller expects negative errno
93 MOVW R3, ret+24(FP)
94 RET
95
96 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
97 MOVW fd+0(FP), R3
98 MOVD p+8(FP), R4
99 MOVW n+16(FP), R5
100 SYSCALL $SYS_read
101 BVC 2(PC)
102 NEG R3 // caller expects negative errno
103 MOVW R3, ret+24(FP)
104 RET
105
106 // func pipe() (r, w int32, errno int32)
107 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
108 ADD $FIXED_FRAME, R1, R3
109 SYSCALL $SYS_pipe
110 MOVW R3, errno+8(FP)
111 RET
112
113 // func pipe2(flags int32) (r, w int32, errno int32)
114 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
115 ADD $FIXED_FRAME+8, R1, R3
116 MOVW flags+0(FP), R4
117 SYSCALL $SYS_pipe2
118 MOVW R3, errno+16(FP)
119 RET
120
121 TEXT runtime·usleep(SB),NOSPLIT,$16-4
122 MOVW usec+0(FP), R3
123 MOVD R3, R5
124 MOVW $1000000, R4
125 DIVD R4, R3
126 MOVD R3, 8(R1)
127 MOVW $1000, R4
128 MULLD R3, R4
129 SUB R4, R5
130 MOVD R5, 16(R1)
131
132 // nanosleep(&ts, 0)
133 ADD $8, R1, R3
134 MOVW $0, R4
135 SYSCALL $SYS_nanosleep
136 RET
137
138 TEXT runtime·gettid(SB),NOSPLIT,$0-4
139 SYSCALL $SYS_gettid
140 MOVW R3, ret+0(FP)
141 RET
142
143 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
144 SYSCALL $SYS_getpid
145 MOVW R3, R14
146 SYSCALL $SYS_gettid
147 MOVW R3, R4 // arg 2 tid
148 MOVW R14, R3 // arg 1 pid
149 MOVW sig+0(FP), R5 // arg 3
150 SYSCALL $SYS_tgkill
151 RET
152
153 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
154 SYSCALL $SYS_getpid
155 MOVW R3, R3 // arg 1 pid
156 MOVW sig+0(FP), R4 // arg 2
157 SYSCALL $SYS_kill
158 RET
159
160 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
161 SYSCALL $SYS_getpid
162 MOVD R3, ret+0(FP)
163 RET
164
165 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
166 MOVD tgid+0(FP), R3
167 MOVD tid+8(FP), R4
168 MOVD sig+16(FP), R5
169 SYSCALL $SYS_tgkill
170 RET
171
172 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
173 MOVW mode+0(FP), R3
174 MOVD new+8(FP), R4
175 MOVD old+16(FP), R5
176 SYSCALL $SYS_setitimer
177 RET
178
179 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
180 MOVD addr+0(FP), R3
181 MOVD n+8(FP), R4
182 MOVD dst+16(FP), R5
183 SYSCALL $SYS_mincore
184 NEG R3 // caller expects negative errno
185 MOVW R3, ret+24(FP)
186 RET
187
188 // func walltime() (sec int64, nsec int32)
189 TEXT runtime·walltime(SB),NOSPLIT,$16-12
190 MOVD R1, R15 // R15 is unchanged by C code
191 MOVD g_m(g), R21 // R21 = m
192
193 MOVD $0, R3 // CLOCK_REALTIME
194
195 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
196 CMP R12, R0
197 BEQ fallback
198
199 // Set vdsoPC and vdsoSP for SIGPROF traceback.
200 // Save the old values on stack and restore them on exit,
201 // so this function is reentrant.
202 MOVD m_vdsoPC(R21), R4
203 MOVD m_vdsoSP(R21), R5
204 MOVD R4, 32(R1)
205 MOVD R5, 40(R1)
206
207 MOVD LR, R14
208 MOVD R14, m_vdsoPC(R21)
209 MOVD R15, m_vdsoSP(R21)
210
211 MOVD m_curg(R21), R6
212 CMP g, R6
213 BNE noswitch
214
215 MOVD m_g0(R21), R7
216 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
217
218 noswitch:
219 SUB $16, R1 // Space for results
220 RLDICR $0, R1, $59, R1 // Align for C code
221 MOVD R12, CTR
222 MOVD R1, R4
223
224 // Store g on gsignal's stack, so if we receive a signal
225 // during VDSO code we can find the g.
226 // If we don't have a signal stack, we won't receive signal,
227 // so don't bother saving g.
228 // When using cgo, we already saved g on TLS, also don't save
229 // g here.
230 // Also don't save g if we are already on the signal stack.
231 // We won't get a nested signal.
232 MOVBZ runtime·iscgo(SB), R22
233 CMP R22, $0
234 BNE nosaveg
235 MOVD m_gsignal(R21), R22 // g.m.gsignal
236 CMP R22, $0
237 BEQ nosaveg
238
239 CMP g, R22
240 BEQ nosaveg
241 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
242 MOVD g, (R22)
243
244 BL (CTR) // Call from VDSO
245
246 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
247
248 JMP finish
249
250 nosaveg:
251 BL (CTR) // Call from VDSO
252
253 finish:
254 MOVD $0, R0 // Restore R0
255 MOVD 0(R1), R3 // sec
256 MOVD 8(R1), R5 // nsec
257 MOVD R15, R1 // Restore SP
258
259 // Restore vdsoPC, vdsoSP
260 // We don't worry about being signaled between the two stores.
261 // If we are not in a signal handler, we'll restore vdsoSP to 0,
262 // and no one will care about vdsoPC. If we are in a signal handler,
263 // we cannot receive another signal.
264 MOVD 40(R1), R6
265 MOVD R6, m_vdsoSP(R21)
266 MOVD 32(R1), R6
267 MOVD R6, m_vdsoPC(R21)
268
269 return:
270 MOVD R3, sec+0(FP)
271 MOVW R5, nsec+8(FP)
272 RET
273
274 // Syscall fallback
275 fallback:
276 ADD $32, R1, R4
277 SYSCALL $SYS_clock_gettime
278 MOVD 32(R1), R3
279 MOVD 40(R1), R5
280 JMP return
281
282 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
283 MOVD $1, R3 // CLOCK_MONOTONIC
284
285 MOVD R1, R15 // R15 is unchanged by C code
286 MOVD g_m(g), R21 // R21 = m
287
288 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
289 CMP R12, R0
290 BEQ fallback
291
292 // Set vdsoPC and vdsoSP for SIGPROF traceback.
293 // Save the old values on stack and restore them on exit,
294 // so this function is reentrant.
295 MOVD m_vdsoPC(R21), R4
296 MOVD m_vdsoSP(R21), R5
297 MOVD R4, 32(R1)
298 MOVD R5, 40(R1)
299
300 MOVD LR, R14 // R14 is unchanged by C code
301 MOVD R14, m_vdsoPC(R21)
302 MOVD R15, m_vdsoSP(R21)
303
304 MOVD m_curg(R21), R6
305 CMP g, R6
306 BNE noswitch
307
308 MOVD m_g0(R21), R7
309 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
310
311 noswitch:
312 SUB $16, R1 // Space for results
313 RLDICR $0, R1, $59, R1 // Align for C code
314 MOVD R12, CTR
315 MOVD R1, R4
316
317 // Store g on gsignal's stack, so if we receive a signal
318 // during VDSO code we can find the g.
319 // If we don't have a signal stack, we won't receive signal,
320 // so don't bother saving g.
321 // When using cgo, we already saved g on TLS, also don't save
322 // g here.
323 // Also don't save g if we are already on the signal stack.
324 // We won't get a nested signal.
325 MOVBZ runtime·iscgo(SB), R22
326 CMP R22, $0
327 BNE nosaveg
328 MOVD m_gsignal(R21), R22 // g.m.gsignal
329 CMP R22, $0
330 BEQ nosaveg
331
332 CMP g, R22
333 BEQ nosaveg
334 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
335 MOVD g, (R22)
336
337 BL (CTR) // Call from VDSO
338
339 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
340
341 JMP finish
342
343 nosaveg:
344 BL (CTR) // Call from VDSO
345
346 finish:
347 MOVD $0, R0 // Restore R0
348 MOVD 0(R1), R3 // sec
349 MOVD 8(R1), R5 // nsec
350 MOVD R15, R1 // Restore SP
351
352 // Restore vdsoPC, vdsoSP
353 // We don't worry about being signaled between the two stores.
354 // If we are not in a signal handler, we'll restore vdsoSP to 0,
355 // and no one will care about vdsoPC. If we are in a signal handler,
356 // we cannot receive another signal.
357 MOVD 40(R1), R6
358 MOVD R6, m_vdsoSP(R21)
359 MOVD 32(R1), R6
360 MOVD R6, m_vdsoPC(R21)
361
362 return:
363 // sec is in R3, nsec in R5
364 // return nsec in R3
365 MOVD $1000000000, R4
366 MULLD R4, R3
367 ADD R5, R3
368 MOVD R3, ret+0(FP)
369 RET
370
371 // Syscall fallback
372 fallback:
373 ADD $32, R1, R4
374 SYSCALL $SYS_clock_gettime
375 MOVD 32(R1), R3
376 MOVD 40(R1), R5
377 JMP return
378
379 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
380 MOVW how+0(FP), R3
381 MOVD new+8(FP), R4
382 MOVD old+16(FP), R5
383 MOVW size+24(FP), R6
384 SYSCALL $SYS_rt_sigprocmask
385 BVC 2(PC)
386 MOVD R0, 0xf0(R0) // crash
387 RET
388
389 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
390 MOVD sig+0(FP), R3
391 MOVD new+8(FP), R4
392 MOVD old+16(FP), R5
393 MOVD size+24(FP), R6
394 SYSCALL $SYS_rt_sigaction
395 BVC 2(PC)
396 NEG R3 // caller expects negative errno
397 MOVW R3, ret+32(FP)
398 RET
399
400 #ifdef GOARCH_ppc64le
401 // Call the function stored in _cgo_sigaction using the GCC calling convention.
402 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
403 MOVD sig+0(FP), R3
404 MOVD new+8(FP), R4
405 MOVD old+16(FP), R5
406 MOVD _cgo_sigaction(SB), R12
407 MOVD R12, CTR // R12 should contain the function address
408 MOVD R1, R15 // Save R1
409 MOVD R2, 24(R1) // Save R2
410 SUB $48, R1 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
411 RLDICR $0, R1, $59, R1 // Align to 16 bytes for C code
412 BL (CTR)
413 XOR R0, R0, R0 // Clear R0 as Go expects
414 MOVD R15, R1 // Restore R1
415 MOVD 24(R1), R2 // Restore R2
416 MOVW R3, ret+24(FP) // Return result
417 RET
418 #endif
419
420 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
421 MOVW sig+8(FP), R3
422 MOVD info+16(FP), R4
423 MOVD ctx+24(FP), R5
424 MOVD fn+0(FP), R12
425 MOVD R12, CTR
426 BL (CTR)
427 MOVD 24(R1), R2
428 RET
429
430 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
431 RET
432
433 #ifdef GOARCH_ppc64le
434 // ppc64le doesn't need function descriptors
435 // Save callee-save registers in the case of signal forwarding.
436 // Same as on ARM64 https://golang.org/issue/31827 .
437 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
438 #else
439 // function descriptor for the real sigtramp
440 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
441 DWORD $sigtramp<>(SB)
442 DWORD $0
443 DWORD $0
444 TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
445 #endif
446 // Start with standard C stack frame layout and linkage.
447 MOVD LR, R0
448 MOVD R0, 16(R1) // Save LR in caller's frame.
449 MOVW CR, R0 // Save CR in caller's frame
450 MOVD R0, 8(R1)
451 // The stack must be acquired here and not
452 // in the automatic way based on stack size
453 // since that sequence clobbers R31 before it
454 // gets saved.
455 // We are being ultra safe here in saving the
456 // Vregs. The case where they might need to
457 // be saved is very unlikely.
458 MOVDU R1, -544(R1)
459 MOVD R14, 64(R1)
460 MOVD R15, 72(R1)
461 MOVD R16, 80(R1)
462 MOVD R17, 88(R1)
463 MOVD R18, 96(R1)
464 MOVD R19, 104(R1)
465 MOVD R20, 112(R1)
466 MOVD R21, 120(R1)
467 MOVD R22, 128(R1)
468 MOVD R23, 136(R1)
469 MOVD R24, 144(R1)
470 MOVD R25, 152(R1)
471 MOVD R26, 160(R1)
472 MOVD R27, 168(R1)
473 MOVD R28, 176(R1)
474 MOVD R29, 184(R1)
475 MOVD g, 192(R1) // R30
476 MOVD R31, 200(R1)
477 FMOVD F14, 208(R1)
478 FMOVD F15, 216(R1)
479 FMOVD F16, 224(R1)
480 FMOVD F17, 232(R1)
481 FMOVD F18, 240(R1)
482 FMOVD F19, 248(R1)
483 FMOVD F20, 256(R1)
484 FMOVD F21, 264(R1)
485 FMOVD F22, 272(R1)
486 FMOVD F23, 280(R1)
487 FMOVD F24, 288(R1)
488 FMOVD F25, 296(R1)
489 FMOVD F26, 304(R1)
490 FMOVD F27, 312(R1)
491 FMOVD F28, 320(R1)
492 FMOVD F29, 328(R1)
493 FMOVD F30, 336(R1)
494 FMOVD F31, 344(R1)
495 // Save V regs
496 // STXVD2X and LXVD2X used since
497 // we aren't sure of alignment.
498 // Endianness doesn't matter
499 // if we are just loading and
500 // storing values.
501 MOVD $352, R7 // V20
502 STXVD2X VS52, (R7)(R1)
503 ADD $16, R7 // V21 368
504 STXVD2X VS53, (R7)(R1)
505 ADD $16, R7 // V22 384
506 STXVD2X VS54, (R7)(R1)
507 ADD $16, R7 // V23 400
508 STXVD2X VS55, (R7)(R1)
509 ADD $16, R7 // V24 416
510 STXVD2X VS56, (R7)(R1)
511 ADD $16, R7 // V25 432
512 STXVD2X VS57, (R7)(R1)
513 ADD $16, R7 // V26 448
514 STXVD2X VS58, (R7)(R1)
515 ADD $16, R7 // V27 464
516 STXVD2X VS59, (R7)(R1)
517 ADD $16, R7 // V28 480
518 STXVD2X VS60, (R7)(R1)
519 ADD $16, R7 // V29 496
520 STXVD2X VS61, (R7)(R1)
521 ADD $16, R7 // V30 512
522 STXVD2X VS62, (R7)(R1)
523 ADD $16, R7 // V31 528
524 STXVD2X VS63, (R7)(R1)
525
526 // initialize essential registers (just in case)
527 BL runtime·reginit(SB)
528
529 // this might be called in external code context,
530 // where g is not set.
531 MOVBZ runtime·iscgo(SB), R6
532 CMP R6, $0
533 BEQ 2(PC)
534 BL runtime·load_g(SB)
535
536 MOVW R3, FIXED_FRAME+0(R1)
537 MOVD R4, FIXED_FRAME+8(R1)
538 MOVD R5, FIXED_FRAME+16(R1)
539 MOVD $runtime·sigtrampgo(SB), R12
540 MOVD R12, CTR
541 BL (CTR)
542 MOVD 24(R1), R2 // Should this be here? Where is it saved?
543 // Starts at 64; FIXED_FRAME is 32
544 MOVD 64(R1), R14
545 MOVD 72(R1), R15
546 MOVD 80(R1), R16
547 MOVD 88(R1), R17
548 MOVD 96(R1), R18
549 MOVD 104(R1), R19
550 MOVD 112(R1), R20
551 MOVD 120(R1), R21
552 MOVD 128(R1), R22
553 MOVD 136(R1), R23
554 MOVD 144(R1), R24
555 MOVD 152(R1), R25
556 MOVD 160(R1), R26
557 MOVD 168(R1), R27
558 MOVD 176(R1), R28
559 MOVD 184(R1), R29
560 MOVD 192(R1), g // R30
561 MOVD 200(R1), R31
562 FMOVD 208(R1), F14
563 FMOVD 216(R1), F15
564 FMOVD 224(R1), F16
565 FMOVD 232(R1), F17
566 FMOVD 240(R1), F18
567 FMOVD 248(R1), F19
568 FMOVD 256(R1), F20
569 FMOVD 264(R1), F21
570 FMOVD 272(R1), F22
571 FMOVD 280(R1), F23
572 FMOVD 288(R1), F24
573 FMOVD 292(R1), F25
574 FMOVD 300(R1), F26
575 FMOVD 308(R1), F27
576 FMOVD 316(R1), F28
577 FMOVD 328(R1), F29
578 FMOVD 336(R1), F30
579 FMOVD 344(R1), F31
580 MOVD $352, R7
581 LXVD2X (R7)(R1), VS52
582 ADD $16, R7 // 368 V21
583 LXVD2X (R7)(R1), VS53
584 ADD $16, R7 // 384 V22
585 LXVD2X (R7)(R1), VS54
586 ADD $16, R7 // 400 V23
587 LXVD2X (R7)(R1), VS55
588 ADD $16, R7 // 416 V24
589 LXVD2X (R7)(R1), VS56
590 ADD $16, R7 // 432 V25
591 LXVD2X (R7)(R1), VS57
592 ADD $16, R7 // 448 V26
593 LXVD2X (R7)(R1), VS58
594 ADD $16, R8 // 464 V27
595 LXVD2X (R7)(R1), VS59
596 ADD $16, R7 // 480 V28
597 LXVD2X (R7)(R1), VS60
598 ADD $16, R7 // 496 V29
599 LXVD2X (R7)(R1), VS61
600 ADD $16, R7 // 512 V30
601 LXVD2X (R7)(R1), VS62
602 ADD $16, R7 // 528 V31
603 LXVD2X (R7)(R1), VS63
604 ADD $544, R1
605 MOVD 8(R1), R0
606 MOVFL R0, $0xff
607 MOVD 16(R1), R0
608 MOVD R0, LR
609
610 RET
611
612 #ifdef GOARCH_ppc64le
613 // ppc64le doesn't need function descriptors
614 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
615 // The stack unwinder, presumably written in C, may not be able to
616 // handle Go frame correctly. So, this function is NOFRAME, and we
617 // save/restore LR manually.
618 MOVD LR, R10
619
620 // We're coming from C code, initialize essential registers.
621 CALL runtime·reginit(SB)
622
623 // If no traceback function, do usual sigtramp.
624 MOVD runtime·cgoTraceback(SB), R6
625 CMP $0, R6
626 BEQ sigtramp
627
628 // If no traceback support function, which means that
629 // runtime/cgo was not linked in, do usual sigtramp.
630 MOVD _cgo_callers(SB), R6
631 CMP $0, R6
632 BEQ sigtramp
633
634 // Set up g register.
635 CALL runtime·load_g(SB)
636
637 // Figure out if we are currently in a cgo call.
638 // If not, just do usual sigtramp.
639 // compared to ARM64 and others.
640 CMP $0, g
641 BEQ sigtrampnog // g == nil
642 MOVD g_m(g), R6
643 CMP $0, R6
644 BEQ sigtramp // g.m == nil
645 MOVW m_ncgo(R6), R7
646 CMPW $0, R7
647 BEQ sigtramp // g.m.ncgo = 0
648 MOVD m_curg(R6), R7
649 CMP $0, R7
650 BEQ sigtramp // g.m.curg == nil
651 MOVD g_syscallsp(R7), R7
652 CMP $0, R7
653 BEQ sigtramp // g.m.curg.syscallsp == 0
654 MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
655 CMP $0, R7
656 BEQ sigtramp // g.m.cgoCallers == nil
657 MOVW m_cgoCallersUse(R6), R8
658 CMPW $0, R8
659 BNE sigtramp // g.m.cgoCallersUse != 0
660
661 // Jump to a function in runtime/cgo.
662 // That function, written in C, will call the user's traceback
663 // function with proper unwind info, and will then call back here.
664 // The first three arguments, and the fifth, are already in registers.
665 // Set the two remaining arguments now.
666 MOVD runtime·cgoTraceback(SB), R6
667 MOVD $runtime·sigtramp(SB), R8
668 MOVD _cgo_callers(SB), R12
669 MOVD R12, CTR
670 MOVD R10, LR // restore LR
671 JMP (CTR)
672
673 sigtramp:
674 MOVD R10, LR // restore LR
675 JMP runtime·sigtramp(SB)
676
677 sigtrampnog:
678 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
679 // stack trace.
680 CMPW R3, $27 // 27 == SIGPROF
681 BNE sigtramp
682
683 // Lock sigprofCallersUse (cas from 0 to 1).
684 MOVW $1, R7
685 MOVD $runtime·sigprofCallersUse(SB), R8
686 SYNC
687 LWAR (R8), R6
688 CMPW $0, R6
689 BNE sigtramp
690 STWCCC R7, (R8)
691 BNE -4(PC)
692 ISYNC
693
694 // Jump to the traceback function in runtime/cgo.
695 // It will call back to sigprofNonGo, which will ignore the
696 // arguments passed in registers.
697 // First three arguments to traceback function are in registers already.
698 MOVD runtime·cgoTraceback(SB), R6
699 MOVD $runtime·sigprofCallers(SB), R7
700 MOVD $runtime·sigprofNonGoWrapper<>(SB), R8
701 MOVD _cgo_callers(SB), R12
702 MOVD R12, CTR
703 MOVD R10, LR // restore LR
704 JMP (CTR)
705 #else
706 // function descriptor for the real sigtramp
707 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
708 DWORD $cgoSigtramp<>(SB)
709 DWORD $0
710 DWORD $0
711 TEXT cgoSigtramp<>(SB),NOSPLIT,$0
712 JMP sigtramp<>(SB)
713 #endif
714
715 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
716 // We're coming from C code, set up essential register, then call sigprofNonGo.
717 CALL runtime·reginit(SB)
718 CALL runtime·sigprofNonGo(SB)
719 RET
720
721 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
722 MOVD addr+0(FP), R3
723 MOVD n+8(FP), R4
724 MOVW prot+16(FP), R5
725 MOVW flags+20(FP), R6
726 MOVW fd+24(FP), R7
727 MOVW off+28(FP), R8
728
729 SYSCALL $SYS_mmap
730 BVC ok
731 MOVD $0, p+32(FP)
732 MOVD R3, err+40(FP)
733 RET
734 ok:
735 MOVD R3, p+32(FP)
736 MOVD $0, err+40(FP)
737 RET
738
739 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
740 MOVD addr+0(FP), R3
741 MOVD n+8(FP), R4
742 SYSCALL $SYS_munmap
743 BVC 2(PC)
744 MOVD R0, 0xf0(R0)
745 RET
746
747 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
748 MOVD addr+0(FP), R3
749 MOVD n+8(FP), R4
750 MOVW flags+16(FP), R5
751 SYSCALL $SYS_madvise
752 MOVW R3, ret+24(FP)
753 RET
754
755 // int64 futex(int32 *uaddr, int32 op, int32 val,
756 // struct timespec *timeout, int32 *uaddr2, int32 val2);
757 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
758 MOVD addr+0(FP), R3
759 MOVW op+8(FP), R4
760 MOVW val+12(FP), R5
761 MOVD ts+16(FP), R6
762 MOVD addr2+24(FP), R7
763 MOVW val3+32(FP), R8
764 SYSCALL $SYS_futex
765 BVC 2(PC)
766 NEG R3 // caller expects negative errno
767 MOVW R3, ret+40(FP)
768 RET
769
770 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
771 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
772 MOVW flags+0(FP), R3
773 MOVD stk+8(FP), R4
774
775 // Copy mp, gp, fn off parent stack for use by child.
776 // Careful: Linux system call clobbers ???.
777 MOVD mp+16(FP), R7
778 MOVD gp+24(FP), R8
779 MOVD fn+32(FP), R12
780
781 MOVD R7, -8(R4)
782 MOVD R8, -16(R4)
783 MOVD R12, -24(R4)
784 MOVD $1234, R7
785 MOVD R7, -32(R4)
786
787 SYSCALL $SYS_clone
788 BVC 2(PC)
789 NEG R3 // caller expects negative errno
790
791 // In parent, return.
792 CMP R3, $0
793 BEQ 3(PC)
794 MOVW R3, ret+40(FP)
795 RET
796
797 // In child, on new stack.
798 // initialize essential registers
799 BL runtime·reginit(SB)
800 MOVD -32(R1), R7
801 CMP R7, $1234
802 BEQ 2(PC)
803 MOVD R0, 0(R0)
804
805 // Initialize m->procid to Linux tid
806 SYSCALL $SYS_gettid
807
808 MOVD -24(R1), R12 // fn
809 MOVD -16(R1), R8 // g
810 MOVD -8(R1), R7 // m
811
812 CMP R7, $0
813 BEQ nog
814 CMP R8, $0
815 BEQ nog
816
817 MOVD R3, m_procid(R7)
818
819 // TODO: setup TLS.
820
821 // In child, set up new stack
822 MOVD R7, g_m(R8)
823 MOVD R8, g
824 //CALL runtime·stackcheck(SB)
825
826 nog:
827 // Call fn
828 MOVD R12, CTR
829 BL (CTR)
830
831 // It shouldn't return. If it does, exit that thread.
832 MOVW $111, R3
833 SYSCALL $SYS_exit
834 BR -2(PC) // keep exiting
835
836 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
837 MOVD new+0(FP), R3
838 MOVD old+8(FP), R4
839 SYSCALL $SYS_sigaltstack
840 BVC 2(PC)
841 MOVD R0, 0xf0(R0) // crash
842 RET
843
844 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
845 SYSCALL $SYS_sched_yield
846 RET
847
848 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
849 MOVD pid+0(FP), R3
850 MOVD len+8(FP), R4
851 MOVD buf+16(FP), R5
852 SYSCALL $SYS_sched_getaffinity
853 BVC 2(PC)
854 NEG R3 // caller expects negative errno
855 MOVW R3, ret+24(FP)
856 RET
857
858 // int32 runtime·epollcreate(int32 size);
859 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
860 MOVW size+0(FP), R3
861 SYSCALL $SYS_epoll_create
862 BVC 2(PC)
863 NEG R3 // caller expects negative errno
864 MOVW R3, ret+8(FP)
865 RET
866
867 // int32 runtime·epollcreate1(int32 flags);
868 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
869 MOVW flags+0(FP), R3
870 SYSCALL $SYS_epoll_create1
871 BVC 2(PC)
872 NEG R3 // caller expects negative errno
873 MOVW R3, ret+8(FP)
874 RET
875
876 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
877 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
878 MOVW epfd+0(FP), R3
879 MOVW op+4(FP), R4
880 MOVW fd+8(FP), R5
881 MOVD ev+16(FP), R6
882 SYSCALL $SYS_epoll_ctl
883 NEG R3 // caller expects negative errno
884 MOVW R3, ret+24(FP)
885 RET
886
887 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
888 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
889 MOVW epfd+0(FP), R3
890 MOVD ev+8(FP), R4
891 MOVW nev+16(FP), R5
892 MOVW timeout+20(FP), R6
893 SYSCALL $SYS_epoll_wait
894 BVC 2(PC)
895 NEG R3 // caller expects negative errno
896 MOVW R3, ret+24(FP)
897 RET
898
899 // void runtime·closeonexec(int32 fd);
900 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
901 MOVW fd+0(FP), R3 // fd
902 MOVD $2, R4 // F_SETFD
903 MOVD $1, R5 // FD_CLOEXEC
904 SYSCALL $SYS_fcntl
905 RET
906
907 // func runtime·setNonblock(int32 fd)
908 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
909 MOVW fd+0(FP), R3 // fd
910 MOVD $3, R4 // F_GETFL
911 MOVD $0, R5
912 SYSCALL $SYS_fcntl
913 OR $0x800, R3, R5 // O_NONBLOCK
914 MOVW fd+0(FP), R3 // fd
915 MOVD $4, R4 // F_SETFL
916 SYSCALL $SYS_fcntl
917 RET
918
919 // func sbrk0() uintptr
920 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
921 // Implemented as brk(NULL).
922 MOVD $0, R3
923 SYSCALL $SYS_brk
924 MOVD R3, ret+0(FP)
925 RET
926
927 TEXT runtime·access(SB),$0-20
928 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
929 MOVW R0, ret+16(FP) // for vet
930 RET
931
932 TEXT runtime·connect(SB),$0-28
933 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
934 MOVW R0, ret+24(FP) // for vet
935 RET
936
937 TEXT runtime·socket(SB),$0-20
938 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
939 MOVW R0, ret+16(FP) // for vet
940 RET
941
View as plain text