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