Text file
src/runtime/sys_openbsd_ppc64.s
Documentation: runtime
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.
21TEXT 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
44TEXT 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
53TEXT 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.)
75TEXT 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
80TEXT 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
85TEXT 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
91TEXT 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
97TEXT 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
111TEXT 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
118TEXT 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
127TEXT 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
133TEXT 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
140TEXT 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
146TEXT 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
153TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$32
154 CALL libc_sched_yield(SB)
155 RET
156
157TEXT 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
172noerr:
173 MOVD R3, 32(R14)
174 MOVD R4, 40(R14)
175 RET
176
177TEXT 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
187TEXT 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
195TEXT 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
203TEXT runtime·close_trampoline(SB),NOSPLIT,$32
204 MOVW 0(R3), R3 // arg 1 - fd
205 CALL libc_close(SB)
206 RET
207
208TEXT 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
218noerr:
219 RET
220
221TEXT 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
231noerr:
232 RET
233
234TEXT 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
243noerr:
244 RET
245
246TEXT 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
253TEXT runtime·usleep_trampoline(SB),NOSPLIT,$32
254 MOVW 0(R3), R3 // arg 1 - usec
255 CALL libc_usleep(SB)
256 RET
257
258TEXT 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
268TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$32
269 CALL libc_kqueue(SB)
270 RET
271
272TEXT 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
285noerr:
286 RET
287
288TEXT 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
297noerr:
298 RET
299
300TEXT 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
313noerr:
314 MOVW R3, 12(R14)
315 MOVW R4, 16(R14)
316 RET
317
318TEXT 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
329TEXT 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
340TEXT 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
350TEXT 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.
372TEXT 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
397ok:
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.
416TEXT 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
441ok:
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.
463TEXT 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
491ok:
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.
513TEXT 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
541ok:
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).
567TEXT 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
596ok:
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.
625TEXT 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
654ok:
655 RET
View as plain text