Text file
src/runtime/sys_darwin_amd64.s
Documentation: runtime
1 // Copyright 2009 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 AMD64, 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 #include "cgo/abi_amd64.h"
13
14 #define CLOCK_REALTIME 0
15
16 // Exit the entire program (like C exit)
17 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
18 PUSHQ BP
19 MOVQ SP, BP
20 MOVL 0(DI), DI // arg 1 exit status
21 CALL libc_exit(SB)
22 MOVL $0xf1, 0xf1 // crash
23 POPQ BP
24 RET
25
26 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
27 PUSHQ BP
28 MOVQ SP, BP
29 MOVL 8(DI), SI // arg 2 flags
30 MOVL 12(DI), DX // arg 3 mode
31 MOVQ 0(DI), DI // arg 1 pathname
32 XORL AX, AX // vararg: say "no float args"
33 CALL libc_open(SB)
34 POPQ BP
35 RET
36
37 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
38 PUSHQ BP
39 MOVQ SP, BP
40 MOVL 0(DI), DI // arg 1 fd
41 CALL libc_close(SB)
42 POPQ BP
43 RET
44
45 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
46 PUSHQ BP
47 MOVQ SP, BP
48 MOVQ 8(DI), SI // arg 2 buf
49 MOVL 16(DI), DX // arg 3 count
50 MOVL 0(DI), DI // arg 1 fd
51 CALL libc_read(SB)
52 TESTL AX, AX
53 JGE noerr
54 CALL libc_error(SB)
55 MOVL (AX), AX
56 NEGL AX // caller expects negative errno value
57 noerr:
58 POPQ BP
59 RET
60
61 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
62 PUSHQ BP
63 MOVQ SP, BP
64 MOVQ 8(DI), SI // arg 2 buf
65 MOVL 16(DI), DX // arg 3 count
66 MOVQ 0(DI), DI // arg 1 fd
67 CALL libc_write(SB)
68 TESTL AX, AX
69 JGE noerr
70 CALL libc_error(SB)
71 MOVL (AX), AX
72 NEGL AX // caller expects negative errno value
73 noerr:
74 POPQ BP
75 RET
76
77 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
78 PUSHQ BP
79 MOVQ SP, BP
80 CALL libc_pipe(SB) // pointer already in DI
81 TESTL AX, AX
82 JEQ 3(PC)
83 CALL libc_error(SB) // return negative errno value
84 NEGL AX
85 POPQ BP
86 RET
87
88 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
89 PUSHQ BP
90 MOVQ SP, BP
91 MOVQ 8(DI), SI // arg 2 new
92 MOVQ 16(DI), DX // arg 3 old
93 MOVL 0(DI), DI // arg 1 which
94 CALL libc_setitimer(SB)
95 POPQ BP
96 RET
97
98 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
99 PUSHQ BP
100 MOVQ SP, BP
101 MOVQ 8(DI), SI // arg 2 len
102 MOVL 16(DI), DX // arg 3 advice
103 MOVQ 0(DI), DI // arg 1 addr
104 CALL libc_madvise(SB)
105 // ignore failure - maybe pages are locked
106 POPQ BP
107 RET
108
109 TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
110 UNDEF // unimplemented
111
112 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
113
114 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
115 PUSHQ BP
116 MOVQ SP, BP
117 MOVQ DI, BX
118 CALL libc_mach_absolute_time(SB)
119 MOVQ AX, 0(BX)
120 MOVL timebase<>+machTimebaseInfo_numer(SB), SI
121 MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
122 TESTL DI, DI
123 JNE initialized
124
125 SUBQ $(machTimebaseInfo__size+15)/16*16, SP
126 MOVQ SP, DI
127 CALL libc_mach_timebase_info(SB)
128 MOVL machTimebaseInfo_numer(SP), SI
129 MOVL machTimebaseInfo_denom(SP), DI
130 ADDQ $(machTimebaseInfo__size+15)/16*16, SP
131
132 MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
133 MOVL DI, AX
134 XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
135
136 initialized:
137 MOVL SI, 8(BX)
138 MOVL DI, 12(BX)
139 MOVQ BP, SP
140 POPQ BP
141 RET
142
143 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
144 PUSHQ BP // make a frame; keep stack aligned
145 MOVQ SP, BP
146 MOVQ DI, SI // arg 2 timespec
147 MOVL $CLOCK_REALTIME, DI // arg 1 clock_id
148 CALL libc_clock_gettime(SB)
149 POPQ BP
150 RET
151
152 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
153 PUSHQ BP
154 MOVQ SP, BP
155 MOVQ 8(DI), SI // arg 2 new
156 MOVQ 16(DI), DX // arg 3 old
157 MOVL 0(DI), DI // arg 1 sig
158 CALL libc_sigaction(SB)
159 TESTL AX, AX
160 JEQ 2(PC)
161 MOVL $0xf1, 0xf1 // crash
162 POPQ BP
163 RET
164
165 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
166 PUSHQ BP
167 MOVQ SP, BP
168 MOVQ 8(DI), SI // arg 2 new
169 MOVQ 16(DI), DX // arg 3 old
170 MOVL 0(DI), DI // arg 1 how
171 CALL libc_pthread_sigmask(SB)
172 TESTL AX, AX
173 JEQ 2(PC)
174 MOVL $0xf1, 0xf1 // crash
175 POPQ BP
176 RET
177
178 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
179 PUSHQ BP
180 MOVQ SP, BP
181 MOVQ 8(DI), SI // arg 2 old
182 MOVQ 0(DI), DI // arg 1 new
183 CALL libc_sigaltstack(SB)
184 TESTQ AX, AX
185 JEQ 2(PC)
186 MOVL $0xf1, 0xf1 // crash
187 POPQ BP
188 RET
189
190 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
191 PUSHQ BP
192 MOVQ SP, BP
193 MOVL 0(DI), BX // signal
194 CALL libc_getpid(SB)
195 MOVL AX, DI // arg 1 pid
196 MOVL BX, SI // arg 2 signal
197 CALL libc_kill(SB)
198 POPQ BP
199 RET
200
201 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
202 MOVQ fn+0(FP), AX
203 MOVL sig+8(FP), DI
204 MOVQ info+16(FP), SI
205 MOVQ ctx+24(FP), DX
206 PUSHQ BP
207 MOVQ SP, BP
208 ANDQ $~15, SP // alignment for x86_64 ABI
209 CALL AX
210 MOVQ BP, SP
211 POPQ BP
212 RET
213
214 // This is the function registered during sigaction and is invoked when
215 // a signal is received. It just redirects to the Go function sigtrampgo.
216 // Called using C ABI.
217 TEXT runtime·sigtramp(SB),NOSPLIT,$0
218 // Transition from C ABI to Go ABI.
219 PUSH_REGS_HOST_TO_ABI0()
220
221 // Call into the Go signal handler
222 NOP SP // disable vet stack checking
223 ADJSP $24
224 MOVL DI, 0(SP) // sig
225 MOVQ SI, 8(SP) // info
226 MOVQ DX, 16(SP) // ctx
227 CALL ·sigtrampgo(SB)
228 ADJSP $-24
229
230 POP_REGS_HOST_TO_ABI0()
231 RET
232
233 // Used instead of sigtramp in programs that use cgo.
234 // Arguments from kernel are in DI, SI, DX.
235 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
236 // If no traceback function, do usual sigtramp.
237 MOVQ runtime·cgoTraceback(SB), AX
238 TESTQ AX, AX
239 JZ sigtramp
240
241 // If no traceback support function, which means that
242 // runtime/cgo was not linked in, do usual sigtramp.
243 MOVQ _cgo_callers(SB), AX
244 TESTQ AX, AX
245 JZ sigtramp
246
247 // Figure out if we are currently in a cgo call.
248 // If not, just do usual sigtramp.
249 get_tls(CX)
250 MOVQ g(CX),AX
251 TESTQ AX, AX
252 JZ sigtrampnog // g == nil
253 MOVQ g_m(AX), AX
254 TESTQ AX, AX
255 JZ sigtramp // g.m == nil
256 MOVL m_ncgo(AX), CX
257 TESTL CX, CX
258 JZ sigtramp // g.m.ncgo == 0
259 MOVQ m_curg(AX), CX
260 TESTQ CX, CX
261 JZ sigtramp // g.m.curg == nil
262 MOVQ g_syscallsp(CX), CX
263 TESTQ CX, CX
264 JZ sigtramp // g.m.curg.syscallsp == 0
265 MOVQ m_cgoCallers(AX), R8
266 TESTQ R8, R8
267 JZ sigtramp // g.m.cgoCallers == nil
268 MOVL m_cgoCallersUse(AX), CX
269 TESTL CX, CX
270 JNZ sigtramp // g.m.cgoCallersUse != 0
271
272 // Jump to a function in runtime/cgo.
273 // That function, written in C, will call the user's traceback
274 // function with proper unwind info, and will then call back here.
275 // The first three arguments, and the fifth, are already in registers.
276 // Set the two remaining arguments now.
277 MOVQ runtime·cgoTraceback(SB), CX
278 MOVQ $runtime·sigtramp(SB), R9
279 MOVQ _cgo_callers(SB), AX
280 JMP AX
281
282 sigtramp:
283 JMP runtime·sigtramp(SB)
284
285 sigtrampnog:
286 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
287 // stack trace.
288 CMPL DI, $27 // 27 == SIGPROF
289 JNZ sigtramp
290
291 // Lock sigprofCallersUse.
292 MOVL $0, AX
293 MOVL $1, CX
294 MOVQ $runtime·sigprofCallersUse(SB), R11
295 LOCK
296 CMPXCHGL CX, 0(R11)
297 JNZ sigtramp // Skip stack trace if already locked.
298
299 // Jump to the traceback function in runtime/cgo.
300 // It will call back to sigprofNonGo, which will ignore the
301 // arguments passed in registers.
302 // First three arguments to traceback function are in registers already.
303 MOVQ runtime·cgoTraceback(SB), CX
304 MOVQ $runtime·sigprofCallers(SB), R8
305 MOVQ $runtime·sigprofNonGo(SB), R9
306 MOVQ _cgo_callers(SB), AX
307 JMP AX
308
309 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
310 PUSHQ BP // make a frame; keep stack aligned
311 MOVQ SP, BP
312 MOVQ DI, BX
313 MOVQ 0(BX), DI // arg 1 addr
314 MOVQ 8(BX), SI // arg 2 len
315 MOVL 16(BX), DX // arg 3 prot
316 MOVL 20(BX), CX // arg 4 flags
317 MOVL 24(BX), R8 // arg 5 fid
318 MOVL 28(BX), R9 // arg 6 offset
319 CALL libc_mmap(SB)
320 XORL DX, DX
321 CMPQ AX, $-1
322 JNE ok
323 CALL libc_error(SB)
324 MOVLQSX (AX), DX // errno
325 XORL AX, AX
326 ok:
327 MOVQ AX, 32(BX)
328 MOVQ DX, 40(BX)
329 POPQ BP
330 RET
331
332 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
333 PUSHQ BP
334 MOVQ SP, BP
335 MOVQ 8(DI), SI // arg 2 len
336 MOVQ 0(DI), DI // arg 1 addr
337 CALL libc_munmap(SB)
338 TESTQ AX, AX
339 JEQ 2(PC)
340 MOVL $0xf1, 0xf1 // crash
341 POPQ BP
342 RET
343
344 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
345 PUSHQ BP
346 MOVQ SP, BP
347 MOVL 0(DI), DI // arg 1 usec
348 CALL libc_usleep(SB)
349 POPQ BP
350 RET
351
352 TEXT runtime·settls(SB),NOSPLIT,$32
353 // Nothing to do on Darwin, pthread already set thread-local storage up.
354 RET
355
356 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
357 PUSHQ BP
358 MOVQ SP, BP
359 MOVL 8(DI), SI // arg 2 miblen
360 MOVQ 16(DI), DX // arg 3 oldp
361 MOVQ 24(DI), CX // arg 4 oldlenp
362 MOVQ 32(DI), R8 // arg 5 newp
363 MOVQ 40(DI), R9 // arg 6 newlen
364 MOVQ 0(DI), DI // arg 1 mib
365 CALL libc_sysctl(SB)
366 POPQ BP
367 RET
368
369 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
370 PUSHQ BP
371 MOVQ SP, BP
372 MOVQ 8(DI), SI // arg 2 oldp
373 MOVQ 16(DI), DX // arg 3 oldlenp
374 MOVQ 24(DI), CX // arg 4 newp
375 MOVQ 32(DI), R8 // arg 5 newlen
376 MOVQ 0(DI), DI // arg 1 name
377 CALL libc_sysctlbyname(SB)
378 POPQ BP
379 RET
380
381 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
382 PUSHQ BP
383 MOVQ SP, BP
384 CALL libc_kqueue(SB)
385 POPQ BP
386 RET
387
388 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
389 PUSHQ BP
390 MOVQ SP, BP
391 MOVQ 8(DI), SI // arg 2 keventt
392 MOVL 16(DI), DX // arg 3 nch
393 MOVQ 24(DI), CX // arg 4 ev
394 MOVL 32(DI), R8 // arg 5 nev
395 MOVQ 40(DI), R9 // arg 6 ts
396 MOVL 0(DI), DI // arg 1 kq
397 CALL libc_kevent(SB)
398 CMPL AX, $-1
399 JNE ok
400 CALL libc_error(SB)
401 MOVLQSX (AX), AX // errno
402 NEGQ AX // caller wants it as a negative error code
403 ok:
404 POPQ BP
405 RET
406
407 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
408 PUSHQ BP
409 MOVQ SP, BP
410 MOVL 4(DI), SI // arg 2 cmd
411 MOVL 8(DI), DX // arg 3 arg
412 MOVL 0(DI), DI // arg 1 fd
413 XORL AX, AX // vararg: say "no float args"
414 CALL libc_fcntl(SB)
415 POPQ BP
416 RET
417
418 // mstart_stub is the first function executed on a new thread started by pthread_create.
419 // It just does some low-level setup and then calls mstart.
420 // Note: called with the C calling convention.
421 TEXT runtime·mstart_stub(SB),NOSPLIT,$0
422 // DI points to the m.
423 // We are already on m's g0 stack.
424
425 // Transition from C ABI to Go ABI.
426 PUSH_REGS_HOST_TO_ABI0()
427
428 MOVQ m_g0(DI), DX // g
429
430 // Initialize TLS entry.
431 // See cmd/link/internal/ld/sym.go:computeTLSOffset.
432 MOVQ DX, 0x30(GS)
433
434 CALL runtime·mstart(SB)
435
436 POP_REGS_HOST_TO_ABI0()
437
438 // Go is all done with this OS thread.
439 // Tell pthread everything is ok (we never join with this thread, so
440 // the value here doesn't really matter).
441 XORL AX, AX
442 RET
443
444 // These trampolines help convert from Go calling convention to C calling convention.
445 // They should be called with asmcgocall.
446 // A pointer to the arguments is passed in DI.
447 // A single int32 result is returned in AX.
448 // (For more results, make an args/results structure.)
449 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
450 PUSHQ BP // make frame, keep stack 16-byte aligned.
451 MOVQ SP, BP
452 MOVQ 0(DI), DI // arg 1 attr
453 CALL libc_pthread_attr_init(SB)
454 POPQ BP
455 RET
456
457 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
458 PUSHQ BP
459 MOVQ SP, BP
460 MOVQ 8(DI), SI // arg 2 size
461 MOVQ 0(DI), DI // arg 1 attr
462 CALL libc_pthread_attr_getstacksize(SB)
463 POPQ BP
464 RET
465
466 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
467 PUSHQ BP
468 MOVQ SP, BP
469 MOVQ 8(DI), SI // arg 2 state
470 MOVQ 0(DI), DI // arg 1 attr
471 CALL libc_pthread_attr_setdetachstate(SB)
472 POPQ BP
473 RET
474
475 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
476 PUSHQ BP
477 MOVQ SP, BP
478 SUBQ $16, SP
479 MOVQ 0(DI), SI // arg 2 attr
480 MOVQ 8(DI), DX // arg 3 start
481 MOVQ 16(DI), CX // arg 4 arg
482 MOVQ SP, DI // arg 1 &threadid (which we throw away)
483 CALL libc_pthread_create(SB)
484 MOVQ BP, SP
485 POPQ BP
486 RET
487
488 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
489 PUSHQ BP
490 MOVQ SP, BP
491 MOVL 0(DI), DI // arg 1 signal
492 CALL libc_raise(SB)
493 POPQ BP
494 RET
495
496 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
497 PUSHQ BP
498 MOVQ SP, BP
499 MOVQ 8(DI), SI // arg 2 attr
500 MOVQ 0(DI), DI // arg 1 mutex
501 CALL libc_pthread_mutex_init(SB)
502 POPQ BP
503 RET
504
505 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
506 PUSHQ BP
507 MOVQ SP, BP
508 MOVQ 0(DI), DI // arg 1 mutex
509 CALL libc_pthread_mutex_lock(SB)
510 POPQ BP
511 RET
512
513 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
514 PUSHQ BP
515 MOVQ SP, BP
516 MOVQ 0(DI), DI // arg 1 mutex
517 CALL libc_pthread_mutex_unlock(SB)
518 POPQ BP
519 RET
520
521 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
522 PUSHQ BP
523 MOVQ SP, BP
524 MOVQ 8(DI), SI // arg 2 attr
525 MOVQ 0(DI), DI // arg 1 cond
526 CALL libc_pthread_cond_init(SB)
527 POPQ BP
528 RET
529
530 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
531 PUSHQ BP
532 MOVQ SP, BP
533 MOVQ 8(DI), SI // arg 2 mutex
534 MOVQ 0(DI), DI // arg 1 cond
535 CALL libc_pthread_cond_wait(SB)
536 POPQ BP
537 RET
538
539 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
540 PUSHQ BP
541 MOVQ SP, BP
542 MOVQ 8(DI), SI // arg 2 mutex
543 MOVQ 16(DI), DX // arg 3 timeout
544 MOVQ 0(DI), DI // arg 1 cond
545 CALL libc_pthread_cond_timedwait_relative_np(SB)
546 POPQ BP
547 RET
548
549 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
550 PUSHQ BP
551 MOVQ SP, BP
552 MOVQ 0(DI), DI // arg 1 cond
553 CALL libc_pthread_cond_signal(SB)
554 POPQ BP
555 RET
556
557 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
558 PUSHQ BP
559 MOVQ SP, BP
560 MOVQ DI, BX // BX is caller-save
561 CALL libc_pthread_self(SB)
562 MOVQ AX, 0(BX) // return value
563 POPQ BP
564 RET
565
566 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
567 PUSHQ BP
568 MOVQ SP, BP
569 MOVQ 8(DI), SI // arg 2 sig
570 MOVQ 0(DI), DI // arg 1 thread
571 CALL libc_pthread_kill(SB)
572 POPQ BP
573 RET
574
575 // syscall calls a function in libc on behalf of the syscall package.
576 // syscall takes a pointer to a struct like:
577 // struct {
578 // fn uintptr
579 // a1 uintptr
580 // a2 uintptr
581 // a3 uintptr
582 // r1 uintptr
583 // r2 uintptr
584 // err uintptr
585 // }
586 // syscall must be called on the g0 stack with the
587 // C calling convention (use libcCall).
588 //
589 // syscall expects a 32-bit result and tests for 32-bit -1
590 // to decide there was an error.
591 TEXT runtime·syscall(SB),NOSPLIT,$0
592 PUSHQ BP
593 MOVQ SP, BP
594 SUBQ $16, SP
595 MOVQ (0*8)(DI), CX // fn
596 MOVQ (2*8)(DI), SI // a2
597 MOVQ (3*8)(DI), DX // a3
598 MOVQ DI, (SP)
599 MOVQ (1*8)(DI), DI // a1
600 XORL AX, AX // vararg: say "no float args"
601
602 CALL CX
603
604 MOVQ (SP), DI
605 MOVQ AX, (4*8)(DI) // r1
606 MOVQ DX, (5*8)(DI) // r2
607
608 // Standard libc functions return -1 on error
609 // and set errno.
610 CMPL AX, $-1 // Note: high 32 bits are junk
611 JNE ok
612
613 // Get error code from libc.
614 CALL libc_error(SB)
615 MOVLQSX (AX), AX
616 MOVQ (SP), DI
617 MOVQ AX, (6*8)(DI) // err
618
619 ok:
620 XORL AX, AX // no error (it's ignored anyway)
621 MOVQ BP, SP
622 POPQ BP
623 RET
624
625 // syscallX calls a function in libc on behalf of the syscall package.
626 // syscallX takes a pointer to a struct like:
627 // struct {
628 // fn uintptr
629 // a1 uintptr
630 // a2 uintptr
631 // a3 uintptr
632 // r1 uintptr
633 // r2 uintptr
634 // err uintptr
635 // }
636 // syscallX must be called on the g0 stack with the
637 // C calling convention (use libcCall).
638 //
639 // syscallX is like syscall but expects a 64-bit result
640 // and tests for 64-bit -1 to decide there was an error.
641 TEXT runtime·syscallX(SB),NOSPLIT,$0
642 PUSHQ BP
643 MOVQ SP, BP
644 SUBQ $16, SP
645 MOVQ (0*8)(DI), CX // fn
646 MOVQ (2*8)(DI), SI // a2
647 MOVQ (3*8)(DI), DX // a3
648 MOVQ DI, (SP)
649 MOVQ (1*8)(DI), DI // a1
650 XORL AX, AX // vararg: say "no float args"
651
652 CALL CX
653
654 MOVQ (SP), DI
655 MOVQ AX, (4*8)(DI) // r1
656 MOVQ DX, (5*8)(DI) // r2
657
658 // Standard libc functions return -1 on error
659 // and set errno.
660 CMPQ AX, $-1
661 JNE ok
662
663 // Get error code from libc.
664 CALL libc_error(SB)
665 MOVLQSX (AX), AX
666 MOVQ (SP), DI
667 MOVQ AX, (6*8)(DI) // err
668
669 ok:
670 XORL AX, AX // no error (it's ignored anyway)
671 MOVQ BP, SP
672 POPQ BP
673 RET
674
675 // syscallPtr is like syscallX except that the libc function reports an
676 // error by returning NULL and setting errno.
677 TEXT runtime·syscallPtr(SB),NOSPLIT,$0
678 PUSHQ BP
679 MOVQ SP, BP
680 SUBQ $16, SP
681 MOVQ (0*8)(DI), CX // fn
682 MOVQ (2*8)(DI), SI // a2
683 MOVQ (3*8)(DI), DX // a3
684 MOVQ DI, (SP)
685 MOVQ (1*8)(DI), DI // a1
686 XORL AX, AX // vararg: say "no float args"
687
688 CALL CX
689
690 MOVQ (SP), DI
691 MOVQ AX, (4*8)(DI) // r1
692 MOVQ DX, (5*8)(DI) // r2
693
694 // syscallPtr libc functions return NULL on error
695 // and set errno.
696 TESTQ AX, AX
697 JNE ok
698
699 // Get error code from libc.
700 CALL libc_error(SB)
701 MOVLQSX (AX), AX
702 MOVQ (SP), DI
703 MOVQ AX, (6*8)(DI) // err
704
705 ok:
706 XORL AX, AX // no error (it's ignored anyway)
707 MOVQ BP, SP
708 POPQ BP
709 RET
710
711 // syscall6 calls a function in libc on behalf of the syscall package.
712 // syscall6 takes a pointer to a struct like:
713 // struct {
714 // fn uintptr
715 // a1 uintptr
716 // a2 uintptr
717 // a3 uintptr
718 // a4 uintptr
719 // a5 uintptr
720 // a6 uintptr
721 // r1 uintptr
722 // r2 uintptr
723 // err uintptr
724 // }
725 // syscall6 must be called on the g0 stack with the
726 // C calling convention (use libcCall).
727 //
728 // syscall6 expects a 32-bit result and tests for 32-bit -1
729 // to decide there was an error.
730 TEXT runtime·syscall6(SB),NOSPLIT,$0
731 PUSHQ BP
732 MOVQ SP, BP
733 SUBQ $16, SP
734 MOVQ (0*8)(DI), R11// fn
735 MOVQ (2*8)(DI), SI // a2
736 MOVQ (3*8)(DI), DX // a3
737 MOVQ (4*8)(DI), CX // a4
738 MOVQ (5*8)(DI), R8 // a5
739 MOVQ (6*8)(DI), R9 // a6
740 MOVQ DI, (SP)
741 MOVQ (1*8)(DI), DI // a1
742 XORL AX, AX // vararg: say "no float args"
743
744 CALL R11
745
746 MOVQ (SP), DI
747 MOVQ AX, (7*8)(DI) // r1
748 MOVQ DX, (8*8)(DI) // r2
749
750 CMPL AX, $-1
751 JNE ok
752
753 CALL libc_error(SB)
754 MOVLQSX (AX), AX
755 MOVQ (SP), DI
756 MOVQ AX, (9*8)(DI) // err
757
758 ok:
759 XORL AX, AX // no error (it's ignored anyway)
760 MOVQ BP, SP
761 POPQ BP
762 RET
763
764 // syscall6X calls a function in libc on behalf of the syscall package.
765 // syscall6X takes a pointer to a struct like:
766 // struct {
767 // fn uintptr
768 // a1 uintptr
769 // a2 uintptr
770 // a3 uintptr
771 // a4 uintptr
772 // a5 uintptr
773 // a6 uintptr
774 // r1 uintptr
775 // r2 uintptr
776 // err uintptr
777 // }
778 // syscall6X must be called on the g0 stack with the
779 // C calling convention (use libcCall).
780 //
781 // syscall6X is like syscall6 but expects a 64-bit result
782 // and tests for 64-bit -1 to decide there was an error.
783 TEXT runtime·syscall6X(SB),NOSPLIT,$0
784 PUSHQ BP
785 MOVQ SP, BP
786 SUBQ $16, SP
787 MOVQ (0*8)(DI), R11// fn
788 MOVQ (2*8)(DI), SI // a2
789 MOVQ (3*8)(DI), DX // a3
790 MOVQ (4*8)(DI), CX // a4
791 MOVQ (5*8)(DI), R8 // a5
792 MOVQ (6*8)(DI), R9 // a6
793 MOVQ DI, (SP)
794 MOVQ (1*8)(DI), DI // a1
795 XORL AX, AX // vararg: say "no float args"
796
797 CALL R11
798
799 MOVQ (SP), DI
800 MOVQ AX, (7*8)(DI) // r1
801 MOVQ DX, (8*8)(DI) // r2
802
803 CMPQ AX, $-1
804 JNE ok
805
806 CALL libc_error(SB)
807 MOVLQSX (AX), AX
808 MOVQ (SP), DI
809 MOVQ AX, (9*8)(DI) // err
810
811 ok:
812 XORL AX, AX // no error (it's ignored anyway)
813 MOVQ BP, SP
814 POPQ BP
815 RET
816
817 // syscallNoErr is like syscall6 but does not check for errors, and
818 // only returns one value, for use with standard C ABI library functions.
819 TEXT runtime·syscallNoErr(SB),NOSPLIT,$0
820 PUSHQ BP
821 MOVQ SP, BP
822 SUBQ $16, SP
823 MOVQ (0*8)(DI), R11// fn
824 MOVQ (2*8)(DI), SI // a2
825 MOVQ (3*8)(DI), DX // a3
826 MOVQ (4*8)(DI), CX // a4
827 MOVQ (5*8)(DI), R8 // a5
828 MOVQ (6*8)(DI), R9 // a6
829 MOVQ DI, (SP)
830 MOVQ (1*8)(DI), DI // a1
831 XORL AX, AX // vararg: say "no float args"
832
833 CALL R11
834
835 MOVQ (SP), DI
836 MOVQ AX, (7*8)(DI) // r1
837
838 XORL AX, AX // no error (it's ignored anyway)
839 MOVQ BP, SP
840 POPQ BP
841 RET
842
View as plain text