Text file
src/runtime/sys_openbsd_ppc64.s
1 // Copyright 2023 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 // System calls and other sys.stuff for ppc64, OpenBSD
6 // System calls are implemented in libc/libpthread, this file
7 // contains trampolines that convert from Go to C calling convention.
8 // Some direct system call implementations currently remain.
9 //
10
11 #include "go_asm.h"
12 #include "go_tls.h"
13 #include "textflag.h"
14
15 #define CLOCK_REALTIME $0
16 #define CLOCK_MONOTONIC $3
17
18 // mstart_stub is the first function executed on a new thread started by pthread_create.
19 // It just does some low-level setup and then calls mstart.
20 // Note: called with the C calling convention.
21 TEXT runtime·mstart_stub(SB),NOSPLIT,$32
22 // R3 points to the m.
23 // We are already on m's g0 stack.
24
25 // Go relies on R0 being $0.
26 XOR R0, R0
27
28 // TODO(jsing): Save callee-save registers (R14-R31, F14-F31, V20-V31).
29
30 MOVD m_g0(R3), g
31 BL runtime·save_g(SB)
32
33 BL runtime·mstart(SB)
34
35 // TODO(jsing): Restore callee-save registers (R14-R31, F14-F31, V20-V31).
36
37 // Go is all done with this OS thread.
38 // Tell pthread everything is ok (we never join with this thread, so
39 // the value here doesn't really matter).
40 MOVD $0, R3
41
42 RET
43
44 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
45 MOVW sig+8(FP), R3
46 MOVD info+16(FP), R4
47 MOVD ctx+24(FP), R5
48 MOVD fn+0(FP), R12
49 MOVD R12, CTR
50 CALL (CTR) // Alignment for ELF ABI?
51 RET
52
53 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$16
54 // Go relies on R0 being $0 and we may have been executing non-Go code.
55 XOR R0, R0
56
57 // TODO(jsing): Save callee-save registers (R2, R14-R31, F14-F31).
58 // in the case of signal forwarding.
59 // Please refer to https://golang.org/issue/31827 .
60
61 // If called from an external code context, g will not be set.
62 BL runtime·load_g(SB)
63
64 BL runtime·sigtrampgo<ABIInternal>(SB)
65
66 // TODO(jsing): Restore callee-save registers.
67
68 RET
69
70 // These trampolines help convert from Go calling convention to C calling convention.
71 // They should be called with asmcgocall.
72 // A pointer to the arguments is passed in R3.
73 // A single int32 result is returned in R3.
74 // (For more results, make an args/results structure.)
75 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$32
76 MOVD 0(R3), R3 // arg 1 - attr
77 CALL libc_pthread_attr_init(SB)
78 RET
79
80 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$32
81 MOVD 0(R3), R3 // arg 1 - attr
82 CALL libc_pthread_attr_destroy(SB)
83 RET
84
85 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$32
86 MOVD 8(R3), R4 // arg 2 - size
87 MOVD 0(R3), R3 // arg 1 - attr
88 CALL libc_pthread_attr_getstacksize(SB)
89 RET
90
91 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$32
92 MOVD 8(R3), R4 // arg 2 - state
93 MOVD 0(R3), R3 // arg 1 - attr
94 CALL libc_pthread_attr_setdetachstate(SB)
95 RET
96
97 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$32
98 MOVD 0(R3), R4 // arg 2 - attr
99 MOVD 8(R3), R5 // arg 3 - start
100 MOVD 16(R3), R6 // arg 4 - arg
101
102 MOVD R1, R15
103 SUB $64, R1
104 RLDCR $0, R1, $~15, R1
105 MOVD R1, R3 // arg 1 - &threadid (discard)
106 CALL libc_pthread_create(SB)
107 MOVD R15, R1
108
109 RET
110
111 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$32
112 MOVD 8(R3), R4 // arg 2 - signal (int64)
113 MOVD $0, R5 // arg 3 - tcb
114 MOVW 0(R3), R3 // arg 1 - tid
115 CALL libc_thrkill(SB)
116 RET
117
118 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$32
119 MOVW 8(R3), R4 // arg 2 - clock_id
120 MOVD 16(R3), R5 // arg 3 - abstime
121 MOVD 24(R3), R6 // arg 4 - lock
122 MOVD 32(R3), R7 // arg 5 - abort
123 MOVD 0(R3), R3 // arg 1 - id
124 CALL libc_thrsleep(SB)
125 RET
126
127 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$32
128 MOVW 8(R3), R4 // arg 2 - count
129 MOVD 0(R3), R3 // arg 1 - id
130 CALL libc_thrwakeup(SB)
131 RET
132
133 TEXT runtime·exit_trampoline(SB),NOSPLIT,$32
134 MOVW 0(R3), R3 // arg 1 - status
135 CALL libc_exit(SB)
136 MOVD $0, R3 // crash on failure
137 MOVD R3, (R3)
138 RET
139
140 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$32
141 MOVD R3, R14 // pointer to args
142 CALL libc_getthrid(SB)
143 MOVW R3, 0(R14) // return value
144 RET
145
146 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$32
147 MOVD R3, R14 // pointer to args
148 CALL libc_getpid(SB) // arg 1 - pid
149 MOVW 0(R14), R4 // arg 2 - signal
150 CALL libc_kill(SB)
151 RET
152
153 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$32
154 CALL libc_sched_yield(SB)
155 RET
156
157 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$32
158 MOVD R3, R14 // pointer to args
159 MOVD 0(R14), R3 // arg 1 - addr
160 MOVD 8(R14), R4 // arg 2 - len
161 MOVW 16(R14), R5 // arg 3 - prot
162 MOVW 20(R14), R6 // arg 4 - flags
163 MOVW 24(R14), R7 // arg 5 - fid
164 MOVW 28(R14), R8 // arg 6 - offset
165 CALL libc_mmap(SB)
166 MOVD $0, R4
167 CMP R3, $-1
168 BNE noerr
169 CALL libc_errno(SB)
170 MOVW (R3), R4 // errno
171 MOVD $0, R3
172 noerr:
173 MOVD R3, 32(R14)
174 MOVD R4, 40(R14)
175 RET
176
177 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$32
178 MOVD 8(R3), R4 // arg 2 - len
179 MOVD 0(R3), R3 // arg 1 - addr
180 CALL libc_munmap(SB)
181 CMP R3, $-1
182 BNE 3(PC)
183 MOVD $0, R3 // crash on failure
184 MOVD R3, (R3)
185 RET
186
187 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$32
188 MOVD 8(R3), R4 // arg 2 - len
189 MOVW 16(R3), R5 // arg 3 - advice
190 MOVD 0(R3), R3 // arg 1 - addr
191 CALL libc_madvise(SB)
192 // ignore failure - maybe pages are locked
193 RET
194
195 TEXT runtime·open_trampoline(SB),NOSPLIT,$32
196 MOVW 8(R3), R4 // arg 2 - flags
197 MOVW 12(R3), R5 // arg 3 - mode
198 MOVD 0(R3), R3 // arg 1 - path
199 MOVD $0, R6 // varargs
200 CALL libc_open(SB)
201 RET
202
203 TEXT runtime·close_trampoline(SB),NOSPLIT,$32
204 MOVW 0(R3), R3 // arg 1 - fd
205 CALL libc_close(SB)
206 RET
207
208 TEXT runtime·read_trampoline(SB),NOSPLIT,$32
209 MOVD 8(R3), R4 // arg 2 - buf
210 MOVW 16(R3), R5 // arg 3 - count
211 MOVW 0(R3), R3 // arg 1 - fd (int32)
212 CALL libc_read(SB)
213 CMP R3, $-1
214 BNE noerr
215 CALL libc_errno(SB)
216 MOVW (R3), R3 // errno
217 NEG R3, R3 // caller expects negative errno value
218 noerr:
219 RET
220
221 TEXT runtime·write_trampoline(SB),NOSPLIT,$32
222 MOVD 8(R3), R4 // arg 2 - buf
223 MOVW 16(R3), R5 // arg 3 - count
224 MOVD 0(R3), R3 // arg 1 - fd (uintptr)
225 CALL libc_write(SB)
226 CMP R3, $-1
227 BNE noerr
228 CALL libc_errno(SB)
229 MOVW (R3), R3 // errno
230 NEG R3, R3 // caller expects negative errno value
231 noerr:
232 RET
233
234 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$32
235 MOVW 8(R3), R4 // arg 2 - flags
236 MOVD 0(R3), R3 // arg 1 - filedes
237 CALL libc_pipe2(SB)
238 CMP R3, $-1
239 BNE noerr
240 CALL libc_errno(SB)
241 MOVW (R3), R3 // errno
242 NEG R3, R3 // caller expects negative errno value
243 noerr:
244 RET
245
246 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$32
247 MOVD 8(R3), R4 // arg 2 - new
248 MOVD 16(R3), R5 // arg 3 - old
249 MOVW 0(R3), R3 // arg 1 - which
250 CALL libc_setitimer(SB)
251 RET
252
253 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$32
254 MOVW 0(R3), R3 // arg 1 - usec
255 CALL libc_usleep(SB)
256 RET
257
258 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$32
259 MOVW 8(R3), R4 // arg 2 - miblen
260 MOVD 16(R3), R5 // arg 3 - out
261 MOVD 24(R3), R6 // arg 4 - size
262 MOVD 32(R3), R7 // arg 5 - dst
263 MOVD 40(R3), R8 // arg 6 - ndst
264 MOVD 0(R3), R3 // arg 1 - mib
265 CALL libc_sysctl(SB)
266 RET
267
268 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$32
269 CALL libc_kqueue(SB)
270 RET
271
272 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$32
273 MOVD 8(R3), R4 // arg 2 - keventt
274 MOVW 16(R3), R5 // arg 3 - nch
275 MOVD 24(R3), R6 // arg 4 - ev
276 MOVW 32(R3), R7 // arg 5 - nev
277 MOVD 40(R3), R8 // arg 6 - ts
278 MOVW 0(R3), R3 // arg 1 - kq
279 CALL libc_kevent(SB)
280 CMP R3, $-1
281 BNE noerr
282 CALL libc_errno(SB)
283 MOVW (R3), R3 // errno
284 NEG R3, R3 // caller expects negative errno value
285 noerr:
286 RET
287
288 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$32
289 MOVD 8(R3), R4 // arg 2 - tp
290 MOVW 0(R3), R3 // arg 1 - clock_id
291 CALL libc_clock_gettime(SB)
292 CMP R3, $-1
293 BNE noerr
294 CALL libc_errno(SB)
295 MOVW (R3), R3 // errno
296 NEG R3, R3 // caller expects negative errno value
297 noerr:
298 RET
299
300 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$32
301 MOVD R3, R14 // pointer to args
302 MOVW 0(R14), R3 // arg 1 - fd
303 MOVW 4(R14), R4 // arg 2 - cmd
304 MOVW 8(R14), R5 // arg 3 - arg
305 MOVD $0, R6 // vararg
306 CALL libc_fcntl(SB)
307 MOVD $0, R4
308 CMP R3, $-1
309 BNE noerr
310 CALL libc_errno(SB)
311 MOVW (R3), R4 // errno
312 MOVW $-1, R3
313 noerr:
314 MOVW R3, 12(R14)
315 MOVW R4, 16(R14)
316 RET
317
318 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$32
319 MOVD 8(R3), R4 // arg 2 - new
320 MOVD 16(R3), R5 // arg 3 - old
321 MOVW 0(R3), R3 // arg 1 - sig
322 CALL libc_sigaction(SB)
323 CMP R3, $-1
324 BNE 3(PC)
325 MOVD $0, R3 // crash on syscall failure
326 MOVD R3, (R3)
327 RET
328
329 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$32
330 MOVD 8(R3), R4 // arg 2 - new
331 MOVD 16(R3), R5 // arg 3 - old
332 MOVW 0(R3), R3 // arg 1 - how
333 CALL libc_pthread_sigmask(SB)
334 CMP R3, $-1
335 BNE 3(PC)
336 MOVD $0, R3 // crash on syscall failure
337 MOVD R3, (R3)
338 RET
339
340 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$32
341 MOVD 8(R3), R4 // arg 2 - old
342 MOVD 0(R3), R3 // arg 1 - new
343 CALL libc_sigaltstack(SB)
344 CMP R3, $-1
345 BNE 3(PC)
346 MOVD $0, R3 // crash on syscall failure
347 MOVD R3, (R3)
348 RET
349
350 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$32
351 MOVD R3, R14 // pointer to args
352 CALL libc_getthrid(SB)
353 MOVW R3, 0(R14) // return value
354 RET
355
356 // syscall calls a function in libc on behalf of the syscall package.
357 // syscall takes a pointer to a struct like:
358 // struct {
359 // fn uintptr
360 // a1 uintptr
361 // a2 uintptr
362 // a3 uintptr
363 // r1 uintptr
364 // r2 uintptr
365 // err uintptr
366 // }
367 // syscall must be called on the g0 stack with the
368 // C calling convention (use libcCall).
369 //
370 // syscall expects a 32-bit result and tests for 32-bit -1
371 // to decide there was an error.
372 TEXT runtime·syscall(SB),NOSPLIT,$32
373 MOVD R3, R14 // pointer to args
374
375 MOVD (0*8)(R14), R12 // fn
376 MOVD (1*8)(R14), R3 // a1
377 MOVD (2*8)(R14), R4 // a2
378 MOVD (3*8)(R14), R5 // a3
379 MOVD $0, R6 // vararg
380
381 MOVD R12, CTR
382 CALL (CTR)
383
384 MOVD R3, (4*8)(R14) // r1
385 MOVD R4, (5*8)(R14) // r2
386
387 // Standard libc functions return -1 on error
388 // and set errno.
389 CMPW R3, $-1
390 BNE ok
391
392 // Get error code from libc.
393 CALL libc_errno(SB)
394 MOVW (R3), R3
395 MOVD R3, (6*8)(R14) // err
396
397 ok:
398 RET
399
400 // syscallX calls a function in libc on behalf of the syscall package.
401 // syscallX takes a pointer to a struct like:
402 // struct {
403 // fn uintptr
404 // a1 uintptr
405 // a2 uintptr
406 // a3 uintptr
407 // r1 uintptr
408 // r2 uintptr
409 // err uintptr
410 // }
411 // syscallX must be called on the g0 stack with the
412 // C calling convention (use libcCall).
413 //
414 // syscallX is like syscall but expects a 64-bit result
415 // and tests for 64-bit -1 to decide there was an error.
416 TEXT runtime·syscallX(SB),NOSPLIT,$32
417 MOVD R3, R14 // pointer to args
418
419 MOVD (0*8)(R14), R12 // fn
420 MOVD (1*8)(R14), R3 // a1
421 MOVD (2*8)(R14), R4 // a2
422 MOVD (3*8)(R14), R5 // a3
423 MOVD $0, R6 // vararg
424
425 MOVD R12, CTR
426 CALL (CTR)
427
428 MOVD R3, (4*8)(R14) // r1
429 MOVD R4, (5*8)(R14) // r2
430
431 // Standard libc functions return -1 on error
432 // and set errno.
433 CMP R3, $-1
434 BNE ok
435
436 // Get error code from libc.
437 CALL libc_errno(SB)
438 MOVW (R3), R3
439 MOVD R3, (6*8)(R14) // err
440
441 ok:
442 RET
443
444 // syscall6 calls a function in libc on behalf of the syscall package.
445 // syscall6 takes a pointer to a struct like:
446 // struct {
447 // fn uintptr
448 // a1 uintptr
449 // a2 uintptr
450 // a3 uintptr
451 // a4 uintptr
452 // a5 uintptr
453 // a6 uintptr
454 // r1 uintptr
455 // r2 uintptr
456 // err uintptr
457 // }
458 // syscall6 must be called on the g0 stack with the
459 // C calling convention (use libcCall).
460 //
461 // syscall6 expects a 32-bit result and tests for 32-bit -1
462 // to decide there was an error.
463 TEXT runtime·syscall6(SB),NOSPLIT,$32
464 MOVD R3, R14 // pointer to args
465
466 MOVD (0*8)(R14), R12 // fn
467 MOVD (1*8)(R14), R3 // a1
468 MOVD (2*8)(R14), R4 // a2
469 MOVD (3*8)(R14), R5 // a3
470 MOVD (4*8)(R14), R6 // a4
471 MOVD (5*8)(R14), R7 // a5
472 MOVD (6*8)(R14), R8 // a6
473 MOVD $0, R9 // vararg
474
475 MOVD R12, CTR
476 CALL (CTR)
477
478 MOVD R3, (7*8)(R14) // r1
479 MOVD R4, (8*8)(R14) // r2
480
481 // Standard libc functions return -1 on error
482 // and set errno.
483 CMPW R3, $-1
484 BNE ok
485
486 // Get error code from libc.
487 CALL libc_errno(SB)
488 MOVW (R3), R3
489 MOVD R3, (9*8)(R14) // err
490
491 ok:
492 RET
493
494 // syscall6X calls a function in libc on behalf of the syscall package.
495 // syscall6X takes a pointer to a struct like:
496 // struct {
497 // fn uintptr
498 // a1 uintptr
499 // a2 uintptr
500 // a3 uintptr
501 // a4 uintptr
502 // a5 uintptr
503 // a6 uintptr
504 // r1 uintptr
505 // r2 uintptr
506 // err uintptr
507 // }
508 // syscall6X must be called on the g0 stack with the
509 // C calling convention (use libcCall).
510 //
511 // syscall6X is like syscall6 but expects a 64-bit result
512 // and tests for 64-bit -1 to decide there was an error.
513 TEXT runtime·syscall6X(SB),NOSPLIT,$32
514 MOVD R3, R14 // pointer to args
515
516 MOVD (0*8)(R14), R12 // fn
517 MOVD (1*8)(R14), R3 // a1
518 MOVD (2*8)(R14), R4 // a2
519 MOVD (3*8)(R14), R5 // a3
520 MOVD (4*8)(R14), R6 // a4
521 MOVD (5*8)(R14), R7 // a5
522 MOVD (6*8)(R14), R8 // a6
523 MOVD $0, R9 // vararg
524
525 MOVD R12, CTR
526 CALL (CTR)
527
528 MOVD R3, (7*8)(R14) // r1
529 MOVD R4, (8*8)(R14) // r2
530
531 // Standard libc functions return -1 on error
532 // and set errno.
533 CMP R3, $-1
534 BNE ok
535
536 // Get error code from libc.
537 CALL libc_errno(SB)
538 MOVW (R3), R3
539 MOVD R3, (9*8)(R14) // err
540
541 ok:
542 RET
543
544 // syscall10 calls a function in libc on behalf of the syscall package.
545 // syscall10 takes a pointer to a struct like:
546 // struct {
547 // fn uintptr
548 // a1 uintptr
549 // a2 uintptr
550 // a3 uintptr
551 // a4 uintptr
552 // a5 uintptr
553 // a6 uintptr
554 // a7 uintptr
555 // a8 uintptr
556 // a9 uintptr
557 // a10 uintptr
558 // r1 uintptr
559 // r2 uintptr
560 // err uintptr
561 // }
562 // syscall10 must be called on the g0 stack with the
563 // C calling convention (use libcCall). Note that this is
564 // really syscall8 as a maximum of eight parameters can be
565 // passed via registers (and current usage does not exceed
566 // this).
567 TEXT runtime·syscall10(SB),NOSPLIT,$32
568 MOVD R3, R14 // pointer to args
569
570 MOVD (0*8)(R14), R12 // fn
571 MOVD (1*8)(R14), R3 // a1
572 MOVD (2*8)(R14), R4 // a2
573 MOVD (3*8)(R14), R5 // a3
574 MOVD (4*8)(R14), R6 // a4
575 MOVD (5*8)(R14), R7 // a5
576 MOVD (6*8)(R14), R8 // a6
577 MOVD (7*8)(R14), R9 // a7
578 MOVD (8*8)(R14), R10 // a8
579
580 MOVD R12, CTR
581 CALL (CTR)
582
583 MOVD R3, (11*8)(R14) // r1
584 MOVD R4, (12*8)(R14) // r2
585
586 // Standard libc functions return -1 on error
587 // and set errno.
588 CMPW R3, $-1
589 BNE ok
590
591 // Get error code from libc.
592 CALL libc_errno(SB)
593 MOVW (R3), R3
594 MOVD R3, (13*8)(R14) // err
595
596 ok:
597 RET
598
599 // syscall10X calls a function in libc on behalf of the syscall package.
600 // syscall10X takes a pointer to a struct like:
601 // struct {
602 // fn uintptr
603 // a1 uintptr
604 // a2 uintptr
605 // a3 uintptr
606 // a4 uintptr
607 // a5 uintptr
608 // a6 uintptr
609 // a7 uintptr
610 // a8 uintptr
611 // a9 uintptr
612 // a10 uintptr
613 // r1 uintptr
614 // r2 uintptr
615 // err uintptr
616 // }
617 // syscall10X must be called on the g0 stack with the
618 // C calling convention (use libcCall). Note that this is
619 // really syscall8X as a maximum of eight parameters can be
620 // passed via registers (and current usage does not exceed
621 // this).
622 //
623 // syscall10X is like syscall10 but expects a 64-bit result
624 // and tests for 64-bit -1 to decide there was an error.
625 TEXT runtime·syscall10X(SB),NOSPLIT,$32
626 MOVD R3, R14 // pointer to args
627
628 MOVD (0*8)(R14), R12 // fn
629 MOVD (1*8)(R14), R3 // a1
630 MOVD (2*8)(R14), R4 // a2
631 MOVD (3*8)(R14), R5 // a3
632 MOVD (4*8)(R14), R6 // a4
633 MOVD (5*8)(R14), R7 // a5
634 MOVD (6*8)(R14), R8 // a6
635 MOVD (7*8)(R14), R9 // a7
636 MOVD (8*8)(R14), R10 // a8
637
638 MOVD R12, CTR
639 CALL (CTR)
640
641 MOVD R3, (11*8)(R14) // r1
642 MOVD R4, (12*8)(R14) // r2
643
644 // Standard libc functions return -1 on error
645 // and set errno.
646 CMP R3, $-1
647 BNE ok
648
649 // Get error code from libc.
650 CALL libc_errno(SB)
651 MOVW (R3), R3
652 MOVD R3, (13*8)(R14) // err
653
654 ok:
655 RET
656
View as plain text