Text file
src/runtime/sys_darwin_arm64.s
1 // Copyright 2015 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, Darwin
6 // System calls are implemented in libSystem, this file contains
7 // trampolines that convert from Go to C calling convention.
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define CLOCK_REALTIME 0
14
15 TEXT notok<>(SB),NOSPLIT,$0
16 MOVD $0, R8
17 MOVD R8, (R8)
18 B 0(PC)
19
20 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
21 SUB $16, RSP
22 MOVW 8(R0), R1 // arg 2 flags
23 MOVW 12(R0), R2 // arg 3 mode
24 MOVW R2, (RSP) // arg 3 is variadic, pass on stack
25 MOVD 0(R0), R0 // arg 1 pathname
26 BL libc_open(SB)
27 ADD $16, RSP
28 RET
29
30 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
31 MOVW 0(R0), R0 // arg 1 fd
32 BL libc_close(SB)
33 RET
34
35 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
36 MOVD 8(R0), R1 // arg 2 buf
37 MOVW 16(R0), R2 // arg 3 count
38 MOVW 0(R0), R0 // arg 1 fd
39 BL libc_write(SB)
40 MOVD $-1, R1
41 CMP R0, R1
42 BNE noerr
43 BL libc_error(SB)
44 MOVW (R0), R0
45 NEG R0, R0 // caller expects negative errno value
46 noerr:
47 RET
48
49 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
50 MOVD 8(R0), R1 // arg 2 buf
51 MOVW 16(R0), R2 // arg 3 count
52 MOVW 0(R0), R0 // arg 1 fd
53 BL libc_read(SB)
54 MOVD $-1, R1
55 CMP R0, R1
56 BNE noerr
57 BL libc_error(SB)
58 MOVW (R0), R0
59 NEG R0, R0 // caller expects negative errno value
60 noerr:
61 RET
62
63 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
64 BL libc_pipe(SB) // pointer already in R0
65 CMP $0, R0
66 BEQ 3(PC)
67 BL libc_error(SB) // return negative errno value
68 NEG R0, R0
69 RET
70
71 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
72 MOVW 0(R0), R0
73 BL libc_exit(SB)
74 MOVD $1234, R0
75 MOVD $1002, R1
76 MOVD R0, (R1) // fail hard
77
78 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
79 MOVD 0(R0), R19 // signal
80 BL libc_getpid(SB)
81 // arg 1 pid already in R0 from getpid
82 MOVD R19, R1 // arg 2 signal
83 BL libc_kill(SB)
84 RET
85
86 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
87 MOVD R0, R19
88 MOVD 0(R19), R0 // arg 1 addr
89 MOVD 8(R19), R1 // arg 2 len
90 MOVW 16(R19), R2 // arg 3 prot
91 MOVW 20(R19), R3 // arg 4 flags
92 MOVW 24(R19), R4 // arg 5 fd
93 MOVW 28(R19), R5 // arg 6 off
94 BL libc_mmap(SB)
95 MOVD $0, R1
96 MOVD $-1, R2
97 CMP R0, R2
98 BNE ok
99 BL libc_error(SB)
100 MOVW (R0), R1
101 MOVD $0, R0
102 ok:
103 MOVD R0, 32(R19) // ret 1 p
104 MOVD R1, 40(R19) // ret 2 err
105 RET
106
107 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
108 MOVD 8(R0), R1 // arg 2 len
109 MOVD 0(R0), R0 // arg 1 addr
110 BL libc_munmap(SB)
111 CMP $0, R0
112 BEQ 2(PC)
113 BL notok<>(SB)
114 RET
115
116 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
117 MOVD 8(R0), R1 // arg 2 len
118 MOVW 16(R0), R2 // arg 3 advice
119 MOVD 0(R0), R0 // arg 1 addr
120 BL libc_madvise(SB)
121 RET
122
123 TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
124 MOVD 8(R0), R1 // arg 2 len
125 MOVD 0(R0), R0 // arg 1 addr
126 BL libc_mlock(SB)
127 RET
128
129 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
130 MOVD 8(R0), R1 // arg 2 new
131 MOVD 16(R0), R2 // arg 3 old
132 MOVW 0(R0), R0 // arg 1 which
133 BL libc_setitimer(SB)
134 RET
135
136 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
137 MOVD R0, R1 // arg 2 timespec
138 MOVW $CLOCK_REALTIME, R0 // arg 1 clock_id
139 BL libc_clock_gettime(SB)
140 RET
141
142 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
143
144 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
145 MOVD R0, R19
146 BL libc_mach_absolute_time(SB)
147 MOVD R0, 0(R19)
148 MOVW timebase<>+machTimebaseInfo_numer(SB), R20
149 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
150 LDARW (R21), R21 // atomic read
151 CMP $0, R21
152 BNE initialized
153
154 SUB $(machTimebaseInfo__size+15)/16*16, RSP
155 MOVD RSP, R0
156 BL libc_mach_timebase_info(SB)
157 MOVW machTimebaseInfo_numer(RSP), R20
158 MOVW machTimebaseInfo_denom(RSP), R21
159 ADD $(machTimebaseInfo__size+15)/16*16, RSP
160
161 MOVW R20, timebase<>+machTimebaseInfo_numer(SB)
162 MOVD $timebase<>+machTimebaseInfo_denom(SB), R22
163 STLRW R21, (R22) // atomic write
164
165 initialized:
166 MOVW R20, 8(R19)
167 MOVW R21, 12(R19)
168 RET
169
170 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
171 MOVW sig+8(FP), R0
172 MOVD info+16(FP), R1
173 MOVD ctx+24(FP), R2
174 MOVD fn+0(FP), R11
175 BL (R11)
176 RET
177
178 TEXT runtime·sigtramp(SB),NOSPLIT,$192
179 // Save callee-save registers in the case of signal forwarding.
180 // Please refer to https://golang.org/issue/31827 .
181 MOVD R19, 8*4(RSP)
182 MOVD R20, 8*5(RSP)
183 MOVD R21, 8*6(RSP)
184 MOVD R22, 8*7(RSP)
185 MOVD R23, 8*8(RSP)
186 MOVD R24, 8*9(RSP)
187 MOVD R25, 8*10(RSP)
188 MOVD R26, 8*11(RSP)
189 MOVD R27, 8*12(RSP)
190 MOVD g, 8*13(RSP)
191 MOVD R29, 8*14(RSP)
192 FMOVD F8, 8*15(RSP)
193 FMOVD F9, 8*16(RSP)
194 FMOVD F10, 8*17(RSP)
195 FMOVD F11, 8*18(RSP)
196 FMOVD F12, 8*19(RSP)
197 FMOVD F13, 8*20(RSP)
198 FMOVD F14, 8*21(RSP)
199 FMOVD F15, 8*22(RSP)
200
201 // Save arguments.
202 MOVW R0, (8*1)(RSP) // sig
203 MOVD R1, (8*2)(RSP) // info
204 MOVD R2, (8*3)(RSP) // ctx
205
206 // this might be called in external code context,
207 // where g is not set.
208 BL runtime·load_g(SB)
209
210 #ifdef GOOS_ios
211 MOVD RSP, R6
212 CMP $0, g
213 BEQ nog
214 // iOS always use the main stack to run the signal handler.
215 // We need to switch to gsignal ourselves.
216 MOVD g_m(g), R11
217 MOVD m_gsignal(R11), R5
218 MOVD (g_stack+stack_hi)(R5), R6
219
220 nog:
221 // Restore arguments.
222 MOVW (8*1)(RSP), R0
223 MOVD (8*2)(RSP), R1
224 MOVD (8*3)(RSP), R2
225
226 // Reserve space for args and the stack pointer on the
227 // gsignal stack.
228 SUB $48, R6
229 // Save stack pointer.
230 MOVD RSP, R4
231 MOVD R4, (8*4)(R6)
232 // Switch to gsignal stack.
233 MOVD R6, RSP
234
235 // Save arguments.
236 MOVW R0, (8*1)(RSP)
237 MOVD R1, (8*2)(RSP)
238 MOVD R2, (8*3)(RSP)
239 #endif
240
241 // Call sigtrampgo.
242 MOVD $runtime·sigtrampgo(SB), R11
243 BL (R11)
244
245 #ifdef GOOS_ios
246 // Switch to old stack.
247 MOVD (8*4)(RSP), R5
248 MOVD R5, RSP
249 #endif
250
251 // Restore callee-save registers.
252 MOVD (8*4)(RSP), R19
253 MOVD (8*5)(RSP), R20
254 MOVD (8*6)(RSP), R21
255 MOVD (8*7)(RSP), R22
256 MOVD (8*8)(RSP), R23
257 MOVD (8*9)(RSP), R24
258 MOVD (8*10)(RSP), R25
259 MOVD (8*11)(RSP), R26
260 MOVD (8*12)(RSP), R27
261 MOVD (8*13)(RSP), g
262 MOVD (8*14)(RSP), R29
263 FMOVD (8*15)(RSP), F8
264 FMOVD (8*16)(RSP), F9
265 FMOVD (8*17)(RSP), F10
266 FMOVD (8*18)(RSP), F11
267 FMOVD (8*19)(RSP), F12
268 FMOVD (8*20)(RSP), F13
269 FMOVD (8*21)(RSP), F14
270 FMOVD (8*22)(RSP), F15
271
272 RET
273
274 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
275 JMP runtime·sigtramp(SB)
276
277 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
278 MOVD 8(R0), R1 // arg 2 new
279 MOVD 16(R0), R2 // arg 3 old
280 MOVW 0(R0), R0 // arg 1 how
281 BL libc_pthread_sigmask(SB)
282 CMP $0, R0
283 BEQ 2(PC)
284 BL notok<>(SB)
285 RET
286
287 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
288 MOVD 8(R0), R1 // arg 2 new
289 MOVD 16(R0), R2 // arg 3 old
290 MOVW 0(R0), R0 // arg 1 how
291 BL libc_sigaction(SB)
292 CMP $0, R0
293 BEQ 2(PC)
294 BL notok<>(SB)
295 RET
296
297 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
298 MOVW 0(R0), R0 // arg 1 usec
299 BL libc_usleep(SB)
300 RET
301
302 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
303 MOVW 8(R0), R1 // arg 2 miblen
304 MOVD 16(R0), R2 // arg 3 oldp
305 MOVD 24(R0), R3 // arg 4 oldlenp
306 MOVD 32(R0), R4 // arg 5 newp
307 MOVD 40(R0), R5 // arg 6 newlen
308 MOVD 0(R0), R0 // arg 1 mib
309 BL libc_sysctl(SB)
310 RET
311
312 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
313 MOVD 8(R0), R1 // arg 2 oldp
314 MOVD 16(R0), R2 // arg 3 oldlenp
315 MOVD 24(R0), R3 // arg 4 newp
316 MOVD 32(R0), R4 // arg 5 newlen
317 MOVD 0(R0), R0 // arg 1 name
318 BL libc_sysctlbyname(SB)
319 RET
320
321
322 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
323 BL libc_kqueue(SB)
324 RET
325
326 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
327 MOVD 8(R0), R1 // arg 2 keventt
328 MOVW 16(R0), R2 // arg 3 nch
329 MOVD 24(R0), R3 // arg 4 ev
330 MOVW 32(R0), R4 // arg 5 nev
331 MOVD 40(R0), R5 // arg 6 ts
332 MOVW 0(R0), R0 // arg 1 kq
333 BL libc_kevent(SB)
334 MOVD $-1, R2
335 CMP R0, R2
336 BNE ok
337 BL libc_error(SB)
338 MOVW (R0), R0 // errno
339 NEG R0, R0 // caller wants it as a negative error code
340 ok:
341 RET
342
343 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
344 SUB $16, RSP
345 MOVW 4(R0), R1 // arg 2 cmd
346 MOVW 8(R0), R2 // arg 3 arg
347 MOVW R2, (RSP) // arg 3 is variadic, pass on stack
348 MOVW 0(R0), R0 // arg 1 fd
349 BL libc_fcntl(SB)
350 ADD $16, RSP
351 RET
352
353 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
354 #ifdef GOOS_ios
355 // sigaltstack on iOS is not supported and will always
356 // run the signal handler on the main stack, so our sigtramp has
357 // to do the stack switch ourselves.
358 MOVW $43, R0
359 BL libc_exit(SB)
360 #else
361 MOVD 8(R0), R1 // arg 2 old
362 MOVD 0(R0), R0 // arg 1 new
363 CALL libc_sigaltstack(SB)
364 CBZ R0, 2(PC)
365 BL notok<>(SB)
366 #endif
367 RET
368
369 // Thread related functions
370
371 // mstart_stub is the first function executed on a new thread started by pthread_create.
372 // It just does some low-level setup and then calls mstart.
373 // Note: called with the C calling convention.
374 TEXT runtime·mstart_stub(SB),NOSPLIT,$160
375 // R0 points to the m.
376 // We are already on m's g0 stack.
377
378 // Save callee-save registers.
379 MOVD R19, 8(RSP)
380 MOVD R20, 16(RSP)
381 MOVD R21, 24(RSP)
382 MOVD R22, 32(RSP)
383 MOVD R23, 40(RSP)
384 MOVD R24, 48(RSP)
385 MOVD R25, 56(RSP)
386 MOVD R26, 64(RSP)
387 MOVD R27, 72(RSP)
388 MOVD g, 80(RSP)
389 MOVD R29, 88(RSP)
390 FMOVD F8, 96(RSP)
391 FMOVD F9, 104(RSP)
392 FMOVD F10, 112(RSP)
393 FMOVD F11, 120(RSP)
394 FMOVD F12, 128(RSP)
395 FMOVD F13, 136(RSP)
396 FMOVD F14, 144(RSP)
397 FMOVD F15, 152(RSP)
398
399 MOVD m_g0(R0), g
400 BL ·save_g(SB)
401
402 BL runtime·mstart(SB)
403
404 // Restore callee-save registers.
405 MOVD 8(RSP), R19
406 MOVD 16(RSP), R20
407 MOVD 24(RSP), R21
408 MOVD 32(RSP), R22
409 MOVD 40(RSP), R23
410 MOVD 48(RSP), R24
411 MOVD 56(RSP), R25
412 MOVD 64(RSP), R26
413 MOVD 72(RSP), R27
414 MOVD 80(RSP), g
415 MOVD 88(RSP), R29
416 FMOVD 96(RSP), F8
417 FMOVD 104(RSP), F9
418 FMOVD 112(RSP), F10
419 FMOVD 120(RSP), F11
420 FMOVD 128(RSP), F12
421 FMOVD 136(RSP), F13
422 FMOVD 144(RSP), F14
423 FMOVD 152(RSP), F15
424
425 // Go is all done with this OS thread.
426 // Tell pthread everything is ok (we never join with this thread, so
427 // the value here doesn't really matter).
428 MOVD $0, R0
429
430 RET
431
432 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
433 MOVD 0(R0), R0 // arg 1 attr
434 BL libc_pthread_attr_init(SB)
435 RET
436
437 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
438 MOVD 8(R0), R1 // arg 2 size
439 MOVD 0(R0), R0 // arg 1 attr
440 BL libc_pthread_attr_getstacksize(SB)
441 RET
442
443 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
444 MOVD 8(R0), R1 // arg 2 state
445 MOVD 0(R0), R0 // arg 1 attr
446 BL libc_pthread_attr_setdetachstate(SB)
447 RET
448
449 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
450 SUB $16, RSP
451 MOVD 0(R0), R1 // arg 2 state
452 MOVD 8(R0), R2 // arg 3 start
453 MOVD 16(R0), R3 // arg 4 arg
454 MOVD RSP, R0 // arg 1 &threadid (which we throw away)
455 BL libc_pthread_create(SB)
456 ADD $16, RSP
457 RET
458
459 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
460 MOVW 0(R0), R0 // arg 1 sig
461 BL libc_raise(SB)
462 RET
463
464 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
465 MOVD 8(R0), R1 // arg 2 attr
466 MOVD 0(R0), R0 // arg 1 mutex
467 BL libc_pthread_mutex_init(SB)
468 RET
469
470 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
471 MOVD 0(R0), R0 // arg 1 mutex
472 BL libc_pthread_mutex_lock(SB)
473 RET
474
475 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
476 MOVD 0(R0), R0 // arg 1 mutex
477 BL libc_pthread_mutex_unlock(SB)
478 RET
479
480 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
481 MOVD 8(R0), R1 // arg 2 attr
482 MOVD 0(R0), R0 // arg 1 cond
483 BL libc_pthread_cond_init(SB)
484 RET
485
486 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
487 MOVD 8(R0), R1 // arg 2 mutex
488 MOVD 0(R0), R0 // arg 1 cond
489 BL libc_pthread_cond_wait(SB)
490 RET
491
492 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
493 MOVD 8(R0), R1 // arg 2 mutex
494 MOVD 16(R0), R2 // arg 3 timeout
495 MOVD 0(R0), R0 // arg 1 cond
496 BL libc_pthread_cond_timedwait_relative_np(SB)
497 RET
498
499 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
500 MOVD 0(R0), R0 // arg 1 cond
501 BL libc_pthread_cond_signal(SB)
502 RET
503
504 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
505 MOVD R0, R19 // R19 is callee-save
506 BL libc_pthread_self(SB)
507 MOVD R0, 0(R19) // return value
508 RET
509
510 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
511 MOVD 8(R0), R1 // arg 2 sig
512 MOVD 0(R0), R0 // arg 1 thread
513 BL libc_pthread_kill(SB)
514 RET
515
516 TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0
517 MOVD 8(R0), R1 // arg 2 destructor
518 MOVD 0(R0), R0 // arg 1 *key
519 BL libc_pthread_key_create(SB)
520 RET
521
522 TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0
523 MOVD 8(R0), R1 // arg 2 value
524 MOVD 0(R0), R0 // arg 1 key
525 BL libc_pthread_setspecific(SB)
526 RET
527
528 // syscall calls a function in libc on behalf of the syscall package.
529 // syscall takes a pointer to a struct like:
530 // struct {
531 // fn uintptr
532 // a1 uintptr
533 // a2 uintptr
534 // a3 uintptr
535 // r1 uintptr
536 // r2 uintptr
537 // err uintptr
538 // }
539 // syscall must be called on the g0 stack with the
540 // C calling convention (use libcCall).
541 TEXT runtime·syscall(SB),NOSPLIT,$0
542 SUB $16, RSP // push structure pointer
543 MOVD R0, 8(RSP)
544
545 MOVD 0(R0), R12 // fn
546 MOVD 16(R0), R1 // a2
547 MOVD 24(R0), R2 // a3
548 MOVD 8(R0), R0 // a1
549
550 // If fn is declared as vararg, we have to pass the vararg arguments on the stack.
551 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
552 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
553 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
554 // on the stack as well.
555 // If we ever have other vararg libSystem calls, we might need to handle more cases.
556 MOVD R2, (RSP)
557
558 BL (R12)
559
560 MOVD 8(RSP), R2 // pop structure pointer
561 ADD $16, RSP
562 MOVD R0, 32(R2) // save r1
563 MOVD R1, 40(R2) // save r2
564 CMPW $-1, R0
565 BNE ok
566 SUB $16, RSP // push structure pointer
567 MOVD R2, 8(RSP)
568 BL libc_error(SB)
569 MOVW (R0), R0
570 MOVD 8(RSP), R2 // pop structure pointer
571 ADD $16, RSP
572 MOVD R0, 48(R2) // save err
573 ok:
574 RET
575
576 // syscallX calls a function in libc on behalf of the syscall package.
577 // syscallX takes a pointer to a struct like:
578 // struct {
579 // fn uintptr
580 // a1 uintptr
581 // a2 uintptr
582 // a3 uintptr
583 // r1 uintptr
584 // r2 uintptr
585 // err uintptr
586 // }
587 // syscallX must be called on the g0 stack with the
588 // C calling convention (use libcCall).
589 TEXT runtime·syscallX(SB),NOSPLIT,$0
590 SUB $16, RSP // push structure pointer
591 MOVD R0, (RSP)
592
593 MOVD 0(R0), R12 // fn
594 MOVD 16(R0), R1 // a2
595 MOVD 24(R0), R2 // a3
596 MOVD 8(R0), R0 // a1
597 BL (R12)
598
599 MOVD (RSP), R2 // pop structure pointer
600 ADD $16, RSP
601 MOVD R0, 32(R2) // save r1
602 MOVD R1, 40(R2) // save r2
603 CMP $-1, R0
604 BNE ok
605 SUB $16, RSP // push structure pointer
606 MOVD R2, (RSP)
607 BL libc_error(SB)
608 MOVW (R0), R0
609 MOVD (RSP), R2 // pop structure pointer
610 ADD $16, RSP
611 MOVD R0, 48(R2) // save err
612 ok:
613 RET
614
615 // syscallPtr is like syscallX except that the libc function reports an
616 // error by returning NULL and setting errno.
617 TEXT runtime·syscallPtr(SB),NOSPLIT,$0
618 SUB $16, RSP // push structure pointer
619 MOVD R0, (RSP)
620
621 MOVD 0(R0), R12 // fn
622 MOVD 16(R0), R1 // a2
623 MOVD 24(R0), R2 // a3
624 MOVD 8(R0), R0 // a1
625 BL (R12)
626
627 MOVD (RSP), R2 // pop structure pointer
628 ADD $16, RSP
629 MOVD R0, 32(R2) // save r1
630 MOVD R1, 40(R2) // save r2
631 CMP $0, R0
632 BNE ok
633 SUB $16, RSP // push structure pointer
634 MOVD R2, (RSP)
635 BL libc_error(SB)
636 MOVW (R0), R0
637 MOVD (RSP), R2 // pop structure pointer
638 ADD $16, RSP
639 MOVD R0, 48(R2) // save err
640 ok:
641 RET
642
643 // syscall6 calls a function in libc on behalf of the syscall package.
644 // syscall6 takes a pointer to a struct like:
645 // struct {
646 // fn uintptr
647 // a1 uintptr
648 // a2 uintptr
649 // a3 uintptr
650 // a4 uintptr
651 // a5 uintptr
652 // a6 uintptr
653 // r1 uintptr
654 // r2 uintptr
655 // err uintptr
656 // }
657 // syscall6 must be called on the g0 stack with the
658 // C calling convention (use libcCall).
659 TEXT runtime·syscall6(SB),NOSPLIT,$0
660 SUB $16, RSP // push structure pointer
661 MOVD R0, 8(RSP)
662
663 MOVD 0(R0), R12 // fn
664 MOVD 16(R0), R1 // a2
665 MOVD 24(R0), R2 // a3
666 MOVD 32(R0), R3 // a4
667 MOVD 40(R0), R4 // a5
668 MOVD 48(R0), R5 // a6
669 MOVD 8(R0), R0 // a1
670
671 // If fn is declared as vararg, we have to pass the vararg arguments on the stack.
672 // See syscall above. The only function this applies to is openat, for which the 4th
673 // arg must be on the stack.
674 MOVD R3, (RSP)
675
676 BL (R12)
677
678 MOVD 8(RSP), R2 // pop structure pointer
679 ADD $16, RSP
680 MOVD R0, 56(R2) // save r1
681 MOVD R1, 64(R2) // save r2
682 CMPW $-1, R0
683 BNE ok
684 SUB $16, RSP // push structure pointer
685 MOVD R2, 8(RSP)
686 BL libc_error(SB)
687 MOVW (R0), R0
688 MOVD 8(RSP), R2 // pop structure pointer
689 ADD $16, RSP
690 MOVD R0, 72(R2) // save err
691 ok:
692 RET
693
694 // syscall6X calls a function in libc on behalf of the syscall package.
695 // syscall6X takes a pointer to a struct like:
696 // struct {
697 // fn uintptr
698 // a1 uintptr
699 // a2 uintptr
700 // a3 uintptr
701 // a4 uintptr
702 // a5 uintptr
703 // a6 uintptr
704 // r1 uintptr
705 // r2 uintptr
706 // err uintptr
707 // }
708 // syscall6X must be called on the g0 stack with the
709 // C calling convention (use libcCall).
710 TEXT runtime·syscall6X(SB),NOSPLIT,$0
711 SUB $16, RSP // push structure pointer
712 MOVD R0, (RSP)
713
714 MOVD 0(R0), R12 // fn
715 MOVD 16(R0), R1 // a2
716 MOVD 24(R0), R2 // a3
717 MOVD 32(R0), R3 // a4
718 MOVD 40(R0), R4 // a5
719 MOVD 48(R0), R5 // a6
720 MOVD 8(R0), R0 // a1
721 BL (R12)
722
723 MOVD (RSP), R2 // pop structure pointer
724 ADD $16, RSP
725 MOVD R0, 56(R2) // save r1
726 MOVD R1, 64(R2) // save r2
727 CMP $-1, R0
728 BNE ok
729 SUB $16, RSP // push structure pointer
730 MOVD R2, (RSP)
731 BL libc_error(SB)
732 MOVW (R0), R0
733 MOVD (RSP), R2 // pop structure pointer
734 ADD $16, RSP
735 MOVD R0, 72(R2) // save err
736 ok:
737 RET
738
739 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
740 // takes 5 uintptrs and 1 float64, and only returns one value,
741 // for use with standard C ABI functions.
742 TEXT runtime·syscall_x509(SB),NOSPLIT,$0
743 SUB $16, RSP // push structure pointer
744 MOVD R0, (RSP)
745
746 MOVD 0(R0), R12 // fn
747 MOVD 16(R0), R1 // a2
748 MOVD 24(R0), R2 // a3
749 MOVD 32(R0), R3 // a4
750 MOVD 40(R0), R4 // a5
751 FMOVD 48(R0), F0 // f1
752 MOVD 8(R0), R0 // a1
753 BL (R12)
754
755 MOVD (RSP), R2 // pop structure pointer
756 ADD $16, RSP
757 MOVD R0, 56(R2) // save r1
758 RET
759
View as plain text