Text file src/runtime/sys_darwin_amd64.s
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
13 // Exit the entire program (like C exit)
14 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
15 PUSHQ BP
16 MOVQ SP, BP
17 MOVL 0(DI), DI // arg 1 exit status
18 CALL libc_exit(SB)
19 MOVL $0xf1, 0xf1 // crash
20 POPQ BP
21 RET
22
23 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
24 PUSHQ BP
25 MOVQ SP, BP
26 MOVL 8(DI), SI // arg 2 flags
27 MOVL 12(DI), DX // arg 3 mode
28 MOVQ 0(DI), DI // arg 1 pathname
29 XORL AX, AX // vararg: say "no float args"
30 CALL libc_open(SB)
31 POPQ BP
32 RET
33
34 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
35 PUSHQ BP
36 MOVQ SP, BP
37 MOVL 0(DI), DI // arg 1 fd
38 CALL libc_close(SB)
39 POPQ BP
40 RET
41
42 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
43 PUSHQ BP
44 MOVQ SP, BP
45 MOVQ 8(DI), SI // arg 2 buf
46 MOVL 16(DI), DX // arg 3 count
47 MOVL 0(DI), DI // arg 1 fd
48 CALL libc_read(SB)
49 POPQ BP
50 RET
51
52 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
53 PUSHQ BP
54 MOVQ SP, BP
55 MOVQ 8(DI), SI // arg 2 buf
56 MOVL 16(DI), DX // arg 3 count
57 MOVQ 0(DI), DI // arg 1 fd
58 CALL libc_write(SB)
59 POPQ BP
60 RET
61
62 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
63 PUSHQ BP
64 MOVQ SP, BP
65 CALL libc_pipe(SB) // pointer already in DI
66 TESTL AX, AX
67 JEQ 3(PC)
68 CALL libc_error(SB) // return negative errno value
69 NEGL AX
70 POPQ BP
71 RET
72
73 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
74 PUSHQ BP
75 MOVQ SP, BP
76 MOVQ 8(DI), SI // arg 2 new
77 MOVQ 16(DI), DX // arg 3 old
78 MOVL 0(DI), DI // arg 1 which
79 CALL libc_setitimer(SB)
80 POPQ BP
81 RET
82
83 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
84 PUSHQ BP
85 MOVQ SP, BP
86 MOVQ 8(DI), SI // arg 2 len
87 MOVL 16(DI), DX // arg 3 advice
88 MOVQ 0(DI), DI // arg 1 addr
89 CALL libc_madvise(SB)
90 // ignore failure - maybe pages are locked
91 POPQ BP
92 RET
93
94 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
95
96 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
97 PUSHQ BP
98 MOVQ SP, BP
99 MOVQ DI, BX
100 CALL libc_mach_absolute_time(SB)
101 MOVQ AX, 0(BX)
102 MOVL timebase<>+machTimebaseInfo_numer(SB), SI
103 MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
104 TESTL DI, DI
105 JNE initialized
106
107 SUBQ $(machTimebaseInfo__size+15)/16*16, SP
108 MOVQ SP, DI
109 CALL libc_mach_timebase_info(SB)
110 MOVL machTimebaseInfo_numer(SP), SI
111 MOVL machTimebaseInfo_denom(SP), DI
112 ADDQ $(machTimebaseInfo__size+15)/16*16, SP
113
114 MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
115 MOVL DI, AX
116 XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
117
118 initialized:
119 MOVL SI, 8(BX)
120 MOVL DI, 12(BX)
121 MOVQ BP, SP
122 POPQ BP
123 RET
124
125 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
126 PUSHQ BP // make a frame; keep stack aligned
127 MOVQ SP, BP
128 // DI already has *timeval
129 XORL SI, SI // no timezone needed
130 CALL libc_gettimeofday(SB)
131 POPQ BP
132 RET
133
134 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
135 PUSHQ BP
136 MOVQ SP, BP
137 MOVQ 8(DI), SI // arg 2 new
138 MOVQ 16(DI), DX // arg 3 old
139 MOVL 0(DI), DI // arg 1 sig
140 CALL libc_sigaction(SB)
141 TESTL AX, AX
142 JEQ 2(PC)
143 MOVL $0xf1, 0xf1 // crash
144 POPQ BP
145 RET
146
147 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
148 PUSHQ BP
149 MOVQ SP, BP
150 MOVQ 8(DI), SI // arg 2 new
151 MOVQ 16(DI), DX // arg 3 old
152 MOVL 0(DI), DI // arg 1 how
153 CALL libc_pthread_sigmask(SB)
154 TESTL AX, AX
155 JEQ 2(PC)
156 MOVL $0xf1, 0xf1 // crash
157 POPQ BP
158 RET
159
160 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
161 PUSHQ BP
162 MOVQ SP, BP
163 MOVQ 8(DI), SI // arg 2 old
164 MOVQ 0(DI), DI // arg 1 new
165 CALL libc_sigaltstack(SB)
166 TESTQ AX, AX
167 JEQ 2(PC)
168 MOVL $0xf1, 0xf1 // crash
169 POPQ BP
170 RET
171
172 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
173 PUSHQ BP
174 MOVQ SP, BP
175 MOVL 0(DI), BX // signal
176 CALL libc_getpid(SB)
177 MOVL AX, DI // arg 1 pid
178 MOVL BX, SI // arg 2 signal
179 CALL libc_kill(SB)
180 POPQ BP
181 RET
182
183 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
184 MOVQ fn+0(FP), AX
185 MOVL sig+8(FP), DI
186 MOVQ info+16(FP), SI
187 MOVQ ctx+24(FP), DX
188 PUSHQ BP
189 MOVQ SP, BP
190 ANDQ $~15, SP // alignment for x86_64 ABI
191 CALL AX
192 MOVQ BP, SP
193 POPQ BP
194 RET
195
196 // This is the function registered during sigaction and is invoked when
197 // a signal is received. It just redirects to the Go function sigtrampgo.
198 TEXT runtime·sigtramp(SB),NOSPLIT,$0
199 // This runs on the signal stack, so we have lots of stack available.
200 // We allocate our own stack space, because if we tell the linker
201 // how much we're using, the NOSPLIT check fails.
202 PUSHQ BP
203 MOVQ SP, BP
204 SUBQ $64, SP
205
206 // Save callee-save registers.
207 MOVQ BX, 24(SP)
208 MOVQ R12, 32(SP)
209 MOVQ R13, 40(SP)
210 MOVQ R14, 48(SP)
211 MOVQ R15, 56(SP)
212
213 // Call into the Go signal handler
214 MOVL DI, 0(SP) // sig
215 MOVQ SI, 8(SP) // info
216 MOVQ DX, 16(SP) // ctx
217 CALL runtime·sigtrampgo(SB)
218
219 // Restore callee-save registers.
220 MOVQ 24(SP), BX
221 MOVQ 32(SP), R12
222 MOVQ 40(SP), R13
223 MOVQ 48(SP), R14
224 MOVQ 56(SP), R15
225
226 MOVQ BP, SP
227 POPQ BP
228 RET
229
230 // Used instead of sigtramp in programs that use cgo.
231 // Arguments from kernel are in DI, SI, DX.
232 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
233 // If no traceback function, do usual sigtramp.
234 MOVQ runtime·cgoTraceback(SB), AX
235 TESTQ AX, AX
236 JZ sigtramp
237
238 // If no traceback support function, which means that
239 // runtime/cgo was not linked in, do usual sigtramp.
240 MOVQ _cgo_callers(SB), AX
241 TESTQ AX, AX
242 JZ sigtramp
243
244 // Figure out if we are currently in a cgo call.
245 // If not, just do usual sigtramp.
246 get_tls(CX)
247 MOVQ g(CX),AX
248 TESTQ AX, AX
249 JZ sigtrampnog // g == nil
250 MOVQ g_m(AX), AX
251 TESTQ AX, AX
252 JZ sigtramp // g.m == nil
253 MOVL m_ncgo(AX), CX
254 TESTL CX, CX
255 JZ sigtramp // g.m.ncgo == 0
256 MOVQ m_curg(AX), CX
257 TESTQ CX, CX
258 JZ sigtramp // g.m.curg == nil
259 MOVQ g_syscallsp(CX), CX
260 TESTQ CX, CX
261 JZ sigtramp // g.m.curg.syscallsp == 0
262 MOVQ m_cgoCallers(AX), R8
263 TESTQ R8, R8
264 JZ sigtramp // g.m.cgoCallers == nil
265 MOVL m_cgoCallersUse(AX), CX
266 TESTL CX, CX
267 JNZ sigtramp // g.m.cgoCallersUse != 0
268
269 // Jump to a function in runtime/cgo.
270 // That function, written in C, will call the user's traceback
271 // function with proper unwind info, and will then call back here.
272 // The first three arguments, and the fifth, are already in registers.
273 // Set the two remaining arguments now.
274 MOVQ runtime·cgoTraceback(SB), CX
275 MOVQ $runtime·sigtramp(SB), R9
276 MOVQ _cgo_callers(SB), AX
277 JMP AX
278
279 sigtramp:
280 JMP runtime·sigtramp(SB)
281
282 sigtrampnog:
283 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
284 // stack trace.
285 CMPL DI, $27 // 27 == SIGPROF
286 JNZ sigtramp
287
288 // Lock sigprofCallersUse.
289 MOVL $0, AX
290 MOVL $1, CX
291 MOVQ $runtime·sigprofCallersUse(SB), R11
292 LOCK
293 CMPXCHGL CX, 0(R11)
294 JNZ sigtramp // Skip stack trace if already locked.
295
296 // Jump to the traceback function in runtime/cgo.
297 // It will call back to sigprofNonGo, which will ignore the
298 // arguments passed in registers.
299 // First three arguments to traceback function are in registers already.
300 MOVQ runtime·cgoTraceback(SB), CX
301 MOVQ $runtime·sigprofCallers(SB), R8
302 MOVQ $runtime·sigprofNonGo(SB), R9
303 MOVQ _cgo_callers(SB), AX
304 JMP AX
305
306 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
307 PUSHQ BP // make a frame; keep stack aligned
308 MOVQ SP, BP
309 MOVQ DI, BX
310 MOVQ 0(BX), DI // arg 1 addr
311 MOVQ 8(BX), SI // arg 2 len
312 MOVL 16(BX), DX // arg 3 prot
313 MOVL 20(BX), CX // arg 4 flags
314 MOVL 24(BX), R8 // arg 5 fid
315 MOVL 28(BX), R9 // arg 6 offset
316 CALL libc_mmap(SB)
317 XORL DX, DX
318 CMPQ AX, $-1
319 JNE ok
320 CALL libc_error(SB)
321 MOVLQSX (AX), DX // errno
322 XORL AX, AX
323 ok:
324 MOVQ AX, 32(BX)
325 MOVQ DX, 40(BX)
326 POPQ BP
327 RET
328
329 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
330 PUSHQ BP
331 MOVQ SP, BP
332 MOVQ 8(DI), SI // arg 2 len
333 MOVQ 0(DI), DI // arg 1 addr
334 CALL libc_munmap(SB)
335 TESTQ AX, AX
336 JEQ 2(PC)
337 MOVL $0xf1, 0xf1 // crash
338 POPQ BP
339 RET
340
341 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
342 PUSHQ BP
343 MOVQ SP, BP
344 MOVL 0(DI), DI // arg 1 usec
345 CALL libc_usleep(SB)
346 POPQ BP
347 RET
348
349 TEXT runtime·settls(SB),NOSPLIT,$32
350 // Nothing to do on Darwin, pthread already set thread-local storage up.
351 RET
352
353 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
354 PUSHQ BP
355 MOVQ SP, BP
356 MOVL 8(DI), SI // arg 2 miblen
357 MOVQ 16(DI), DX // arg 3 out
358 MOVQ 24(DI), CX // arg 4 size
359 MOVQ 32(DI), R8 // arg 5 dst
360 MOVQ 40(DI), R9 // arg 6 ndst
361 MOVQ 0(DI), DI // arg 1 mib
362 CALL libc_sysctl(SB)
363 POPQ BP
364 RET
365
366 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
367 PUSHQ BP
368 MOVQ SP, BP
369 CALL libc_kqueue(SB)
370 POPQ BP
371 RET
372
373 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
374 PUSHQ BP
375 MOVQ SP, BP
376 MOVQ 8(DI), SI // arg 2 keventt
377 MOVL 16(DI), DX // arg 3 nch
378 MOVQ 24(DI), CX // arg 4 ev
379 MOVL 32(DI), R8 // arg 5 nev
380 MOVQ 40(DI), R9 // arg 6 ts
381 MOVL 0(DI), DI // arg 1 kq
382 CALL libc_kevent(SB)
383 CMPL AX, $-1
384 JNE ok
385 CALL libc_error(SB)
386 MOVLQSX (AX), AX // errno
387 NEGQ AX // caller wants it as a negative error code
388 ok:
389 POPQ BP
390 RET
391
392 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
393 PUSHQ BP
394 MOVQ SP, BP
395 MOVL 4(DI), SI // arg 2 cmd
396 MOVL 8(DI), DX // arg 3 arg
397 MOVL 0(DI), DI // arg 1 fd
398 XORL AX, AX // vararg: say "no float args"
399 CALL libc_fcntl(SB)
400 POPQ BP
401 RET
402
403 // mstart_stub is the first function executed on a new thread started by pthread_create.
404 // It just does some low-level setup and then calls mstart.
405 // Note: called with the C calling convention.
406 TEXT runtime·mstart_stub(SB),NOSPLIT,$0
407 // DI points to the m.
408 // We are already on m's g0 stack.
409
410 // Save callee-save registers.
411 SUBQ $40, SP
412 MOVQ BX, 0(SP)
413 MOVQ R12, 8(SP)
414 MOVQ R13, 16(SP)
415 MOVQ R14, 24(SP)
416 MOVQ R15, 32(SP)
417
418 MOVQ m_g0(DI), DX // g
419
420 // Initialize TLS entry.
421 // See cmd/link/internal/ld/sym.go:computeTLSOffset.
422 MOVQ DX, 0x30(GS)
423
424 // Someday the convention will be D is always cleared.
425 CLD
426
427 CALL runtime·mstart(SB)
428
429 // Restore callee-save registers.
430 MOVQ 0(SP), BX
431 MOVQ 8(SP), R12
432 MOVQ 16(SP), R13
433 MOVQ 24(SP), R14
434 MOVQ 32(SP), R15
435
436 // Go is all done with this OS thread.
437 // Tell pthread everything is ok (we never join with this thread, so
438 // the value here doesn't really matter).
439 XORL AX, AX
440
441 ADDQ $40, SP
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 // syscall calls a function in libc on behalf of the syscall package.
558 // syscall takes a pointer to a struct like:
559 // struct {
560 // fn uintptr
561 // a1 uintptr
562 // a2 uintptr
563 // a3 uintptr
564 // r1 uintptr
565 // r2 uintptr
566 // err uintptr
567 // }
568 // syscall must be called on the g0 stack with the
569 // C calling convention (use libcCall).
570 //
571 // syscall expects a 32-bit result and tests for 32-bit -1
572 // to decide there was an error.
573 TEXT runtime·syscall(SB),NOSPLIT,$0
574 PUSHQ BP
575 MOVQ SP, BP
576 SUBQ $16, SP
577 MOVQ (0*8)(DI), CX // fn
578 MOVQ (2*8)(DI), SI // a2
579 MOVQ (3*8)(DI), DX // a3
580 MOVQ DI, (SP)
581 MOVQ (1*8)(DI), DI // a1
582 XORL AX, AX // vararg: say "no float args"
583
584 CALL CX
585
586 MOVQ (SP), DI
587 MOVQ AX, (4*8)(DI) // r1
588 MOVQ DX, (5*8)(DI) // r2
589
590 // Standard libc functions return -1 on error
591 // and set errno.
592 CMPL AX, $-1 // Note: high 32 bits are junk
593 JNE ok
594
595 // Get error code from libc.
596 CALL libc_error(SB)
597 MOVLQSX (AX), AX
598 MOVQ (SP), DI
599 MOVQ AX, (6*8)(DI) // err
600
601 ok:
602 XORL AX, AX // no error (it's ignored anyway)
603 MOVQ BP, SP
604 POPQ BP
605 RET
606
607 // syscallX calls a function in libc on behalf of the syscall package.
608 // syscallX takes a pointer to a struct like:
609 // struct {
610 // fn uintptr
611 // a1 uintptr
612 // a2 uintptr
613 // a3 uintptr
614 // r1 uintptr
615 // r2 uintptr
616 // err uintptr
617 // }
618 // syscallX must be called on the g0 stack with the
619 // C calling convention (use libcCall).
620 //
621 // syscallX is like syscall but expects a 64-bit result
622 // and tests for 64-bit -1 to decide there was an error.
623 TEXT runtime·syscallX(SB),NOSPLIT,$0
624 PUSHQ BP
625 MOVQ SP, BP
626 SUBQ $16, SP
627 MOVQ (0*8)(DI), CX // fn
628 MOVQ (2*8)(DI), SI // a2
629 MOVQ (3*8)(DI), DX // a3
630 MOVQ DI, (SP)
631 MOVQ (1*8)(DI), DI // a1
632 XORL AX, AX // vararg: say "no float args"
633
634 CALL CX
635
636 MOVQ (SP), DI
637 MOVQ AX, (4*8)(DI) // r1
638 MOVQ DX, (5*8)(DI) // r2
639
640 // Standard libc functions return -1 on error
641 // and set errno.
642 CMPQ AX, $-1
643 JNE ok
644
645 // Get error code from libc.
646 CALL libc_error(SB)
647 MOVLQSX (AX), AX
648 MOVQ (SP), DI
649 MOVQ AX, (6*8)(DI) // err
650
651 ok:
652 XORL AX, AX // no error (it's ignored anyway)
653 MOVQ BP, SP
654 POPQ BP
655 RET
656
657 // syscallPtr is like syscallX except that the libc function reports an
658 // error by returning NULL and setting errno.
659 TEXT runtime·syscallPtr(SB),NOSPLIT,$0
660 PUSHQ BP
661 MOVQ SP, BP
662 SUBQ $16, SP
663 MOVQ (0*8)(DI), CX // fn
664 MOVQ (2*8)(DI), SI // a2
665 MOVQ (3*8)(DI), DX // a3
666 MOVQ DI, (SP)
667 MOVQ (1*8)(DI), DI // a1
668 XORL AX, AX // vararg: say "no float args"
669
670 CALL CX
671
672 MOVQ (SP), DI
673 MOVQ AX, (4*8)(DI) // r1
674 MOVQ DX, (5*8)(DI) // r2
675
676 // syscallPtr libc functions return NULL on error
677 // and set errno.
678 TESTQ AX, AX
679 JNE ok
680
681 // Get error code from libc.
682 CALL libc_error(SB)
683 MOVLQSX (AX), AX
684 MOVQ (SP), DI
685 MOVQ AX, (6*8)(DI) // err
686
687 ok:
688 XORL AX, AX // no error (it's ignored anyway)
689 MOVQ BP, SP
690 POPQ BP
691 RET
692
693 // syscall6 calls a function in libc on behalf of the syscall package.
694 // syscall6 takes a pointer to a struct like:
695 // struct {
696 // fn uintptr
697 // a1 uintptr
698 // a2 uintptr
699 // a3 uintptr
700 // a4 uintptr
701 // a5 uintptr
702 // a6 uintptr
703 // r1 uintptr
704 // r2 uintptr
705 // err uintptr
706 // }
707 // syscall6 must be called on the g0 stack with the
708 // C calling convention (use libcCall).
709 //
710 // syscall6 expects a 32-bit result and tests for 32-bit -1
711 // to decide there was an error.
712 TEXT runtime·syscall6(SB),NOSPLIT,$0
713 PUSHQ BP
714 MOVQ SP, BP
715 SUBQ $16, SP
716 MOVQ (0*8)(DI), R11// fn
717 MOVQ (2*8)(DI), SI // a2
718 MOVQ (3*8)(DI), DX // a3
719 MOVQ (4*8)(DI), CX // a4
720 MOVQ (5*8)(DI), R8 // a5
721 MOVQ (6*8)(DI), R9 // a6
722 MOVQ DI, (SP)
723 MOVQ (1*8)(DI), DI // a1
724 XORL AX, AX // vararg: say "no float args"
725
726 CALL R11
727
728 MOVQ (SP), DI
729 MOVQ AX, (7*8)(DI) // r1
730 MOVQ DX, (8*8)(DI) // r2
731
732 CMPL AX, $-1
733 JNE ok
734
735 CALL libc_error(SB)
736 MOVLQSX (AX), AX
737 MOVQ (SP), DI
738 MOVQ AX, (9*8)(DI) // err
739
740 ok:
741 XORL AX, AX // no error (it's ignored anyway)
742 MOVQ BP, SP
743 POPQ BP
744 RET
745
746 // syscall6X calls a function in libc on behalf of the syscall package.
747 // syscall6X takes a pointer to a struct like:
748 // struct {
749 // fn uintptr
750 // a1 uintptr
751 // a2 uintptr
752 // a3 uintptr
753 // a4 uintptr
754 // a5 uintptr
755 // a6 uintptr
756 // r1 uintptr
757 // r2 uintptr
758 // err uintptr
759 // }
760 // syscall6X must be called on the g0 stack with the
761 // C calling convention (use libcCall).
762 //
763 // syscall6X is like syscall6 but expects a 64-bit result
764 // and tests for 64-bit -1 to decide there was an error.
765 TEXT runtime·syscall6X(SB),NOSPLIT,$0
766 PUSHQ BP
767 MOVQ SP, BP
768 SUBQ $16, SP
769 MOVQ (0*8)(DI), R11// fn
770 MOVQ (2*8)(DI), SI // a2
771 MOVQ (3*8)(DI), DX // a3
772 MOVQ (4*8)(DI), CX // a4
773 MOVQ (5*8)(DI), R8 // a5
774 MOVQ (6*8)(DI), R9 // a6
775 MOVQ DI, (SP)
776 MOVQ (1*8)(DI), DI // a1
777 XORL AX, AX // vararg: say "no float args"
778
779 CALL R11
780
781 MOVQ (SP), DI
782 MOVQ AX, (7*8)(DI) // r1
783 MOVQ DX, (8*8)(DI) // r2
784
785 CMPQ AX, $-1
786 JNE ok
787
788 CALL libc_error(SB)
789 MOVLQSX (AX), AX
790 MOVQ (SP), DI
791 MOVQ AX, (9*8)(DI) // err
792
793 ok:
794 XORL AX, AX // no error (it's ignored anyway)
795 MOVQ BP, SP
796 POPQ BP
797 RET
View as plain text