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