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