Text file
src/runtime/sys_openbsd_arm64.s
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 noerr
363 CALL libc_errno(SB)
364 MOVW (R0), R0 // errno
365 NEG R0, R0 // caller expects negative errno value
366 noerr:
367 RET
368
369 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
370 MOVW 4(R0), R1 // arg 2 - cmd
371 MOVW 8(R0), R2 // arg 3 - arg
372 MOVW 0(R0), R0 // arg 1 - fd
373 MOVD $0, R3 // vararg
374 CALL libc_fcntl(SB)
375 RET
376
377 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
378 MOVD 8(R0), R1 // arg 2 - new
379 MOVD 16(R0), R2 // arg 3 - old
380 MOVW 0(R0), R0 // arg 1 - sig
381 CALL libc_sigaction(SB)
382 CMP $-1, R0
383 BNE 3(PC)
384 MOVD $0, R0 // crash on syscall failure
385 MOVD R0, (R0)
386 RET
387
388 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
389 MOVD 8(R0), R1 // arg 2 - new
390 MOVD 16(R0), R2 // arg 3 - old
391 MOVW 0(R0), R0 // arg 1 - how
392 CALL libc_pthread_sigmask(SB)
393 CMP $-1, R0
394 BNE 3(PC)
395 MOVD $0, R0 // crash on syscall failure
396 MOVD R0, (R0)
397 RET
398
399 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
400 MOVD 8(R0), R1 // arg 2 - old
401 MOVD 0(R0), R0 // arg 1 - new
402 CALL libc_sigaltstack(SB)
403 CMP $-1, R0
404 BNE 3(PC)
405 MOVD $0, R0 // crash on syscall failure
406 MOVD R0, (R0)
407 RET
408
409 // syscall calls a function in libc on behalf of the syscall package.
410 // syscall takes a pointer to a struct like:
411 // struct {
412 // fn uintptr
413 // a1 uintptr
414 // a2 uintptr
415 // a3 uintptr
416 // r1 uintptr
417 // r2 uintptr
418 // err uintptr
419 // }
420 // syscall must be called on the g0 stack with the
421 // C calling convention (use libcCall).
422 //
423 // syscall expects a 32-bit result and tests for 32-bit -1
424 // to decide there was an error.
425 TEXT runtime·syscall(SB),NOSPLIT,$0
426 MOVD R0, R19 // pointer to args
427
428 MOVD (0*8)(R19), R11 // fn
429 MOVD (1*8)(R19), R0 // a1
430 MOVD (2*8)(R19), R1 // a2
431 MOVD (3*8)(R19), R2 // a3
432 MOVD $0, R3 // vararg
433
434 CALL R11
435
436 MOVD R0, (4*8)(R19) // r1
437 MOVD R1, (5*8)(R19) // r2
438
439 // Standard libc functions return -1 on error
440 // and set errno.
441 CMPW $-1, R0
442 BNE ok
443
444 // Get error code from libc.
445 CALL libc_errno(SB)
446 MOVW (R0), R0
447 MOVD R0, (6*8)(R19) // err
448
449 ok:
450 RET
451
452 // syscallX calls a function in libc on behalf of the syscall package.
453 // syscallX takes a pointer to a struct like:
454 // struct {
455 // fn uintptr
456 // a1 uintptr
457 // a2 uintptr
458 // a3 uintptr
459 // r1 uintptr
460 // r2 uintptr
461 // err uintptr
462 // }
463 // syscallX must be called on the g0 stack with the
464 // C calling convention (use libcCall).
465 //
466 // syscallX is like syscall but expects a 64-bit result
467 // and tests for 64-bit -1 to decide there was an error.
468 TEXT runtime·syscallX(SB),NOSPLIT,$0
469 MOVD R0, R19 // pointer to args
470
471 MOVD (0*8)(R19), R11 // fn
472 MOVD (1*8)(R19), R0 // a1
473 MOVD (2*8)(R19), R1 // a2
474 MOVD (3*8)(R19), R2 // a3
475 MOVD $0, R3 // vararg
476
477 CALL R11
478
479 MOVD R0, (4*8)(R19) // r1
480 MOVD R1, (5*8)(R19) // r2
481
482 // Standard libc functions return -1 on error
483 // and set errno.
484 CMP $-1, R0
485 BNE ok
486
487 // Get error code from libc.
488 CALL libc_errno(SB)
489 MOVW (R0), R0
490 MOVD R0, (6*8)(R19) // err
491
492 ok:
493 RET
494
495 // syscall6 calls a function in libc on behalf of the syscall package.
496 // syscall6 takes a pointer to a struct like:
497 // struct {
498 // fn uintptr
499 // a1 uintptr
500 // a2 uintptr
501 // a3 uintptr
502 // a4 uintptr
503 // a5 uintptr
504 // a6 uintptr
505 // r1 uintptr
506 // r2 uintptr
507 // err uintptr
508 // }
509 // syscall6 must be called on the g0 stack with the
510 // C calling convention (use libcCall).
511 //
512 // syscall6 expects a 32-bit result and tests for 32-bit -1
513 // to decide there was an error.
514 TEXT runtime·syscall6(SB),NOSPLIT,$0
515 MOVD R0, R19 // pointer to args
516
517 MOVD (0*8)(R19), R11 // fn
518 MOVD (1*8)(R19), R0 // a1
519 MOVD (2*8)(R19), R1 // a2
520 MOVD (3*8)(R19), R2 // a3
521 MOVD (4*8)(R19), R3 // a4
522 MOVD (5*8)(R19), R4 // a5
523 MOVD (6*8)(R19), R5 // a6
524 MOVD $0, R6 // vararg
525
526 CALL R11
527
528 MOVD R0, (7*8)(R19) // r1
529 MOVD R1, (8*8)(R19) // r2
530
531 // Standard libc functions return -1 on error
532 // and set errno.
533 CMPW $-1, R0
534 BNE ok
535
536 // Get error code from libc.
537 CALL libc_errno(SB)
538 MOVW (R0), R0
539 MOVD R0, (9*8)(R19) // err
540
541 ok:
542 RET
543
544 // syscall6X calls a function in libc on behalf of the syscall package.
545 // syscall6X 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 // r1 uintptr
555 // r2 uintptr
556 // err uintptr
557 // }
558 // syscall6X must be called on the g0 stack with the
559 // C calling convention (use libcCall).
560 //
561 // syscall6X is like syscall6 but expects a 64-bit result
562 // and tests for 64-bit -1 to decide there was an error.
563 TEXT runtime·syscall6X(SB),NOSPLIT,$0
564 MOVD R0, R19 // pointer to args
565
566 MOVD (0*8)(R19), R11 // fn
567 MOVD (1*8)(R19), R0 // a1
568 MOVD (2*8)(R19), R1 // a2
569 MOVD (3*8)(R19), R2 // a3
570 MOVD (4*8)(R19), R3 // a4
571 MOVD (5*8)(R19), R4 // a5
572 MOVD (6*8)(R19), R5 // a6
573 MOVD $0, R6 // vararg
574
575 CALL R11
576
577 MOVD R0, (7*8)(R19) // r1
578 MOVD R1, (8*8)(R19) // r2
579
580 // Standard libc functions return -1 on error
581 // and set errno.
582 CMP $-1, R0
583 BNE ok
584
585 // Get error code from libc.
586 CALL libc_errno(SB)
587 MOVW (R0), R0
588 MOVD R0, (9*8)(R19) // err
589
590 ok:
591 RET
592
593 // syscall10 calls a function in libc on behalf of the syscall package.
594 // syscall10 takes a pointer to a struct like:
595 // struct {
596 // fn uintptr
597 // a1 uintptr
598 // a2 uintptr
599 // a3 uintptr
600 // a4 uintptr
601 // a5 uintptr
602 // a6 uintptr
603 // a7 uintptr
604 // a8 uintptr
605 // a9 uintptr
606 // a10 uintptr
607 // r1 uintptr
608 // r2 uintptr
609 // err uintptr
610 // }
611 // syscall10 must be called on the g0 stack with the
612 // C calling convention (use libcCall).
613 TEXT runtime·syscall10(SB),NOSPLIT,$0
614 MOVD R0, R19 // pointer to args
615
616 MOVD (0*8)(R19), R11 // fn
617 MOVD (1*8)(R19), R0 // a1
618 MOVD (2*8)(R19), R1 // a2
619 MOVD (3*8)(R19), R2 // a3
620 MOVD (4*8)(R19), R3 // a4
621 MOVD (5*8)(R19), R4 // a5
622 MOVD (6*8)(R19), R5 // a6
623 MOVD (7*8)(R19), R6 // a7
624 MOVD (8*8)(R19), R7 // a8
625 MOVD (9*8)(R19), R8 // a9
626 MOVD (10*8)(R19), R9 // a10
627 MOVD $0, R10 // vararg
628
629 CALL R11
630
631 MOVD R0, (11*8)(R19) // r1
632 MOVD R1, (12*8)(R19) // r2
633
634 // Standard libc functions return -1 on error
635 // and set errno.
636 CMPW $-1, R0
637 BNE ok
638
639 // Get error code from libc.
640 CALL libc_errno(SB)
641 MOVW (R0), R0
642 MOVD R0, (13*8)(R19) // err
643
644 ok:
645 RET
646
647 // syscall10X calls a function in libc on behalf of the syscall package.
648 // syscall10X takes a pointer to a struct like:
649 // struct {
650 // fn uintptr
651 // a1 uintptr
652 // a2 uintptr
653 // a3 uintptr
654 // a4 uintptr
655 // a5 uintptr
656 // a6 uintptr
657 // a7 uintptr
658 // a8 uintptr
659 // a9 uintptr
660 // a10 uintptr
661 // r1 uintptr
662 // r2 uintptr
663 // err uintptr
664 // }
665 // syscall10X must be called on the g0 stack with the
666 // C calling convention (use libcCall).
667 //
668 // syscall10X is like syscall10 but expects a 64-bit result
669 // and tests for 64-bit -1 to decide there was an error.
670 TEXT runtime·syscall10X(SB),NOSPLIT,$0
671 MOVD R0, R19 // pointer to args
672
673 MOVD (0*8)(R19), R11 // fn
674 MOVD (1*8)(R19), R0 // a1
675 MOVD (2*8)(R19), R1 // a2
676 MOVD (3*8)(R19), R2 // a3
677 MOVD (4*8)(R19), R3 // a4
678 MOVD (5*8)(R19), R4 // a5
679 MOVD (6*8)(R19), R5 // a6
680 MOVD (7*8)(R19), R6 // a7
681 MOVD (8*8)(R19), R7 // a8
682 MOVD (9*8)(R19), R8 // a9
683 MOVD (10*8)(R19), R9 // a10
684 MOVD $0, R10 // vararg
685
686 CALL R11
687
688 MOVD R0, (11*8)(R19) // r1
689 MOVD R1, (12*8)(R19) // r2
690
691 // Standard libc functions return -1 on error
692 // and set errno.
693 CMP $-1, R0
694 BNE ok
695
696 // Get error code from libc.
697 CALL libc_errno(SB)
698 MOVW (R0), R0
699 MOVD R0, (13*8)(R19) // err
700
701 ok:
702 RET
703
View as plain text