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 #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 // Called using C ABI.
234 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
235 // Transition from C ABI to Go ABI.
236 PUSH_REGS_HOST_TO_ABI0()
237
238 // Call into the Go signal handler
239 NOP SP // disable vet stack checking
240 ADJSP $24
241 MOVL DI, 0(SP) // sig
242 MOVQ SI, 8(SP) // info
243 MOVQ DX, 16(SP) // ctx
244 CALL ·sigprofNonGo(SB)
245 ADJSP $-24
246
247 POP_REGS_HOST_TO_ABI0()
248 RET
249
250 // Used instead of sigtramp in programs that use cgo.
251 // Arguments from kernel are in DI, SI, DX.
252 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
253 // If no traceback function, do usual sigtramp.
254 MOVQ runtime·cgoTraceback(SB), AX
255 TESTQ AX, AX
256 JZ sigtramp
257
258 // If no traceback support function, which means that
259 // runtime/cgo was not linked in, do usual sigtramp.
260 MOVQ _cgo_callers(SB), AX
261 TESTQ AX, AX
262 JZ sigtramp
263
264 // Figure out if we are currently in a cgo call.
265 // If not, just do usual sigtramp.
266 get_tls(CX)
267 MOVQ g(CX),AX
268 TESTQ AX, AX
269 JZ sigtrampnog // g == nil
270 MOVQ g_m(AX), AX
271 TESTQ AX, AX
272 JZ sigtramp // g.m == nil
273 MOVL m_ncgo(AX), CX
274 TESTL CX, CX
275 JZ sigtramp // g.m.ncgo == 0
276 MOVQ m_curg(AX), CX
277 TESTQ CX, CX
278 JZ sigtramp // g.m.curg == nil
279 MOVQ g_syscallsp(CX), CX
280 TESTQ CX, CX
281 JZ sigtramp // g.m.curg.syscallsp == 0
282 MOVQ m_cgoCallers(AX), R8
283 TESTQ R8, R8
284 JZ sigtramp // g.m.cgoCallers == nil
285 MOVL m_cgoCallersUse(AX), CX
286 TESTL CX, CX
287 JNZ sigtramp // g.m.cgoCallersUse != 0
288
289 // Jump to a function in runtime/cgo.
290 // That function, written in C, will call the user's traceback
291 // function with proper unwind info, and will then call back here.
292 // The first three arguments, and the fifth, are already in registers.
293 // Set the two remaining arguments now.
294 MOVQ runtime·cgoTraceback(SB), CX
295 MOVQ $runtime·sigtramp(SB), R9
296 MOVQ _cgo_callers(SB), AX
297 JMP AX
298
299 sigtramp:
300 JMP runtime·sigtramp(SB)
301
302 sigtrampnog:
303 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
304 // stack trace.
305 CMPL DI, $27 // 27 == SIGPROF
306 JNZ sigtramp
307
308 // Lock sigprofCallersUse.
309 MOVL $0, AX
310 MOVL $1, CX
311 MOVQ $runtime·sigprofCallersUse(SB), R11
312 LOCK
313 CMPXCHGL CX, 0(R11)
314 JNZ sigtramp // Skip stack trace if already locked.
315
316 // Jump to the traceback function in runtime/cgo.
317 // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
318 // the arguments to the Go calling convention.
319 // First three arguments to traceback function are in registers already.
320 MOVQ runtime·cgoTraceback(SB), CX
321 MOVQ $runtime·sigprofCallers(SB), R8
322 MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
323 MOVQ _cgo_callers(SB), AX
324 JMP AX
325
326 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
327 PUSHQ BP // make a frame; keep stack aligned
328 MOVQ SP, BP
329 MOVQ DI, BX
330 MOVQ 0(BX), DI // arg 1 addr
331 MOVQ 8(BX), SI // arg 2 len
332 MOVL 16(BX), DX // arg 3 prot
333 MOVL 20(BX), CX // arg 4 flags
334 MOVL 24(BX), R8 // arg 5 fid
335 MOVL 28(BX), R9 // arg 6 offset
336 CALL libc_mmap(SB)
337 XORL DX, DX
338 CMPQ AX, $-1
339 JNE ok
340 CALL libc_error(SB)
341 MOVLQSX (AX), DX // errno
342 XORL AX, AX
343 ok:
344 MOVQ AX, 32(BX)
345 MOVQ DX, 40(BX)
346 POPQ BP
347 RET
348
349 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
350 PUSHQ BP
351 MOVQ SP, BP
352 MOVQ 8(DI), SI // arg 2 len
353 MOVQ 0(DI), DI // arg 1 addr
354 CALL libc_munmap(SB)
355 TESTQ AX, AX
356 JEQ 2(PC)
357 MOVL $0xf1, 0xf1 // crash
358 POPQ BP
359 RET
360
361 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
362 PUSHQ BP
363 MOVQ SP, BP
364 MOVL 0(DI), DI // arg 1 usec
365 CALL libc_usleep(SB)
366 POPQ BP
367 RET
368
369 TEXT runtime·settls(SB),NOSPLIT,$32
370 // Nothing to do on Darwin, pthread already set thread-local storage up.
371 RET
372
373 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
374 PUSHQ BP
375 MOVQ SP, BP
376 MOVL 8(DI), SI // arg 2 miblen
377 MOVQ 16(DI), DX // arg 3 oldp
378 MOVQ 24(DI), CX // arg 4 oldlenp
379 MOVQ 32(DI), R8 // arg 5 newp
380 MOVQ 40(DI), R9 // arg 6 newlen
381 MOVQ 0(DI), DI // arg 1 mib
382 CALL libc_sysctl(SB)
383 POPQ BP
384 RET
385
386 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
387 PUSHQ BP
388 MOVQ SP, BP
389 MOVQ 8(DI), SI // arg 2 oldp
390 MOVQ 16(DI), DX // arg 3 oldlenp
391 MOVQ 24(DI), CX // arg 4 newp
392 MOVQ 32(DI), R8 // arg 5 newlen
393 MOVQ 0(DI), DI // arg 1 name
394 CALL libc_sysctlbyname(SB)
395 POPQ BP
396 RET
397
398 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
399 PUSHQ BP
400 MOVQ SP, BP
401 CALL libc_kqueue(SB)
402 POPQ BP
403 RET
404
405 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
406 PUSHQ BP
407 MOVQ SP, BP
408 MOVQ 8(DI), SI // arg 2 keventt
409 MOVL 16(DI), DX // arg 3 nch
410 MOVQ 24(DI), CX // arg 4 ev
411 MOVL 32(DI), R8 // arg 5 nev
412 MOVQ 40(DI), R9 // arg 6 ts
413 MOVL 0(DI), DI // arg 1 kq
414 CALL libc_kevent(SB)
415 CMPL AX, $-1
416 JNE ok
417 CALL libc_error(SB)
418 MOVLQSX (AX), AX // errno
419 NEGQ AX // caller wants it as a negative error code
420 ok:
421 POPQ BP
422 RET
423
424 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
425 PUSHQ BP
426 MOVQ SP, BP
427 MOVL 4(DI), SI // arg 2 cmd
428 MOVL 8(DI), DX // arg 3 arg
429 MOVL 0(DI), DI // arg 1 fd
430 XORL AX, AX // vararg: say "no float args"
431 CALL libc_fcntl(SB)
432 POPQ BP
433 RET
434
435 // mstart_stub is the first function executed on a new thread started by pthread_create.
436 // It just does some low-level setup and then calls mstart.
437 // Note: called with the C calling convention.
438 TEXT runtime·mstart_stub(SB),NOSPLIT,$0
439 // DI points to the m.
440 // We are already on m's g0 stack.
441
442 // Transition from C ABI to Go ABI.
443 PUSH_REGS_HOST_TO_ABI0()
444
445 MOVQ m_g0(DI), DX // g
446
447 // Initialize TLS entry.
448 // See cmd/link/internal/ld/sym.go:computeTLSOffset.
449 MOVQ DX, 0x30(GS)
450
451 CALL runtime·mstart(SB)
452
453 POP_REGS_HOST_TO_ABI0()
454
455 // Go is all done with this OS thread.
456 // Tell pthread everything is ok (we never join with this thread, so
457 // the value here doesn't really matter).
458 XORL AX, AX
459 RET
460
461 // These trampolines help convert from Go calling convention to C calling convention.
462 // They should be called with asmcgocall.
463 // A pointer to the arguments is passed in DI.
464 // A single int32 result is returned in AX.
465 // (For more results, make an args/results structure.)
466 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
467 PUSHQ BP // make frame, keep stack 16-byte aligned.
468 MOVQ SP, BP
469 MOVQ 0(DI), DI // arg 1 attr
470 CALL libc_pthread_attr_init(SB)
471 POPQ BP
472 RET
473
474 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
475 PUSHQ BP
476 MOVQ SP, BP
477 MOVQ 8(DI), SI // arg 2 size
478 MOVQ 0(DI), DI // arg 1 attr
479 CALL libc_pthread_attr_getstacksize(SB)
480 POPQ BP
481 RET
482
483 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
484 PUSHQ BP
485 MOVQ SP, BP
486 MOVQ 8(DI), SI // arg 2 state
487 MOVQ 0(DI), DI // arg 1 attr
488 CALL libc_pthread_attr_setdetachstate(SB)
489 POPQ BP
490 RET
491
492 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
493 PUSHQ BP
494 MOVQ SP, BP
495 SUBQ $16, SP
496 MOVQ 0(DI), SI // arg 2 attr
497 MOVQ 8(DI), DX // arg 3 start
498 MOVQ 16(DI), CX // arg 4 arg
499 MOVQ SP, DI // arg 1 &threadid (which we throw away)
500 CALL libc_pthread_create(SB)
501 MOVQ BP, SP
502 POPQ BP
503 RET
504
505 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
506 PUSHQ BP
507 MOVQ SP, BP
508 MOVL 0(DI), DI // arg 1 signal
509 CALL libc_raise(SB)
510 POPQ BP
511 RET
512
513 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
514 PUSHQ BP
515 MOVQ SP, BP
516 MOVQ 8(DI), SI // arg 2 attr
517 MOVQ 0(DI), DI // arg 1 mutex
518 CALL libc_pthread_mutex_init(SB)
519 POPQ BP
520 RET
521
522 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
523 PUSHQ BP
524 MOVQ SP, BP
525 MOVQ 0(DI), DI // arg 1 mutex
526 CALL libc_pthread_mutex_lock(SB)
527 POPQ BP
528 RET
529
530 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
531 PUSHQ BP
532 MOVQ SP, BP
533 MOVQ 0(DI), DI // arg 1 mutex
534 CALL libc_pthread_mutex_unlock(SB)
535 POPQ BP
536 RET
537
538 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
539 PUSHQ BP
540 MOVQ SP, BP
541 MOVQ 8(DI), SI // arg 2 attr
542 MOVQ 0(DI), DI // arg 1 cond
543 CALL libc_pthread_cond_init(SB)
544 POPQ BP
545 RET
546
547 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
548 PUSHQ BP
549 MOVQ SP, BP
550 MOVQ 8(DI), SI // arg 2 mutex
551 MOVQ 0(DI), DI // arg 1 cond
552 CALL libc_pthread_cond_wait(SB)
553 POPQ BP
554 RET
555
556 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
557 PUSHQ BP
558 MOVQ SP, BP
559 MOVQ 8(DI), SI // arg 2 mutex
560 MOVQ 16(DI), DX // arg 3 timeout
561 MOVQ 0(DI), DI // arg 1 cond
562 CALL libc_pthread_cond_timedwait_relative_np(SB)
563 POPQ BP
564 RET
565
566 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
567 PUSHQ BP
568 MOVQ SP, BP
569 MOVQ 0(DI), DI // arg 1 cond
570 CALL libc_pthread_cond_signal(SB)
571 POPQ BP
572 RET
573
574 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
575 PUSHQ BP
576 MOVQ SP, BP
577 MOVQ DI, BX // BX is caller-save
578 CALL libc_pthread_self(SB)
579 MOVQ AX, 0(BX) // return value
580 POPQ BP
581 RET
582
583 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
584 PUSHQ BP
585 MOVQ SP, BP
586 MOVQ 8(DI), SI // arg 2 sig
587 MOVQ 0(DI), DI // arg 1 thread
588 CALL libc_pthread_kill(SB)
589 POPQ BP
590 RET
591
592 // syscall calls a function in libc on behalf of the syscall package.
593 // syscall takes a pointer to a struct like:
594 // struct {
595 // fn uintptr
596 // a1 uintptr
597 // a2 uintptr
598 // a3 uintptr
599 // r1 uintptr
600 // r2 uintptr
601 // err uintptr
602 // }
603 // syscall must be called on the g0 stack with the
604 // C calling convention (use libcCall).
605 //
606 // syscall expects a 32-bit result and tests for 32-bit -1
607 // to decide there was an error.
608 TEXT runtime·syscall(SB),NOSPLIT,$0
609 PUSHQ BP
610 MOVQ SP, BP
611 SUBQ $16, SP
612 MOVQ (0*8)(DI), CX // fn
613 MOVQ (2*8)(DI), SI // a2
614 MOVQ (3*8)(DI), DX // a3
615 MOVQ DI, (SP)
616 MOVQ (1*8)(DI), DI // a1
617 XORL AX, AX // vararg: say "no float args"
618
619 CALL CX
620
621 MOVQ (SP), DI
622 MOVQ AX, (4*8)(DI) // r1
623 MOVQ DX, (5*8)(DI) // r2
624
625 // Standard libc functions return -1 on error
626 // and set errno.
627 CMPL AX, $-1 // Note: high 32 bits are junk
628 JNE ok
629
630 // Get error code from libc.
631 CALL libc_error(SB)
632 MOVLQSX (AX), AX
633 MOVQ (SP), DI
634 MOVQ AX, (6*8)(DI) // err
635
636 ok:
637 XORL AX, AX // no error (it's ignored anyway)
638 MOVQ BP, SP
639 POPQ BP
640 RET
641
642 // syscallX calls a function in libc on behalf of the syscall package.
643 // syscallX takes a pointer to a struct like:
644 // struct {
645 // fn uintptr
646 // a1 uintptr
647 // a2 uintptr
648 // a3 uintptr
649 // r1 uintptr
650 // r2 uintptr
651 // err uintptr
652 // }
653 // syscallX must be called on the g0 stack with the
654 // C calling convention (use libcCall).
655 //
656 // syscallX is like syscall but expects a 64-bit result
657 // and tests for 64-bit -1 to decide there was an error.
658 TEXT runtime·syscallX(SB),NOSPLIT,$0
659 PUSHQ BP
660 MOVQ SP, BP
661 SUBQ $16, SP
662 MOVQ (0*8)(DI), CX // fn
663 MOVQ (2*8)(DI), SI // a2
664 MOVQ (3*8)(DI), DX // a3
665 MOVQ DI, (SP)
666 MOVQ (1*8)(DI), DI // a1
667 XORL AX, AX // vararg: say "no float args"
668
669 CALL CX
670
671 MOVQ (SP), DI
672 MOVQ AX, (4*8)(DI) // r1
673 MOVQ DX, (5*8)(DI) // r2
674
675 // Standard libc functions return -1 on error
676 // and set errno.
677 CMPQ AX, $-1
678 JNE ok
679
680 // Get error code from libc.
681 CALL libc_error(SB)
682 MOVLQSX (AX), AX
683 MOVQ (SP), DI
684 MOVQ AX, (6*8)(DI) // err
685
686 ok:
687 XORL AX, AX // no error (it's ignored anyway)
688 MOVQ BP, SP
689 POPQ BP
690 RET
691
692 // syscallPtr is like syscallX except that the libc function reports an
693 // error by returning NULL and setting errno.
694 TEXT runtime·syscallPtr(SB),NOSPLIT,$0
695 PUSHQ BP
696 MOVQ SP, BP
697 SUBQ $16, SP
698 MOVQ (0*8)(DI), CX // fn
699 MOVQ (2*8)(DI), SI // a2
700 MOVQ (3*8)(DI), DX // a3
701 MOVQ DI, (SP)
702 MOVQ (1*8)(DI), DI // a1
703 XORL AX, AX // vararg: say "no float args"
704
705 CALL CX
706
707 MOVQ (SP), DI
708 MOVQ AX, (4*8)(DI) // r1
709 MOVQ DX, (5*8)(DI) // r2
710
711 // syscallPtr libc functions return NULL on error
712 // and set errno.
713 TESTQ AX, AX
714 JNE ok
715
716 // Get error code from libc.
717 CALL libc_error(SB)
718 MOVLQSX (AX), AX
719 MOVQ (SP), DI
720 MOVQ AX, (6*8)(DI) // err
721
722 ok:
723 XORL AX, AX // no error (it's ignored anyway)
724 MOVQ BP, SP
725 POPQ BP
726 RET
727
728 // syscall6 calls a function in libc on behalf of the syscall package.
729 // syscall6 takes a pointer to a struct like:
730 // struct {
731 // fn uintptr
732 // a1 uintptr
733 // a2 uintptr
734 // a3 uintptr
735 // a4 uintptr
736 // a5 uintptr
737 // a6 uintptr
738 // r1 uintptr
739 // r2 uintptr
740 // err uintptr
741 // }
742 // syscall6 must be called on the g0 stack with the
743 // C calling convention (use libcCall).
744 //
745 // syscall6 expects a 32-bit result and tests for 32-bit -1
746 // to decide there was an error.
747 TEXT runtime·syscall6(SB),NOSPLIT,$0
748 PUSHQ BP
749 MOVQ SP, BP
750 SUBQ $16, SP
751 MOVQ (0*8)(DI), R11// fn
752 MOVQ (2*8)(DI), SI // a2
753 MOVQ (3*8)(DI), DX // a3
754 MOVQ (4*8)(DI), CX // a4
755 MOVQ (5*8)(DI), R8 // a5
756 MOVQ (6*8)(DI), R9 // a6
757 MOVQ DI, (SP)
758 MOVQ (1*8)(DI), DI // a1
759 XORL AX, AX // vararg: say "no float args"
760
761 CALL R11
762
763 MOVQ (SP), DI
764 MOVQ AX, (7*8)(DI) // r1
765 MOVQ DX, (8*8)(DI) // r2
766
767 CMPL AX, $-1
768 JNE ok
769
770 CALL libc_error(SB)
771 MOVLQSX (AX), AX
772 MOVQ (SP), DI
773 MOVQ AX, (9*8)(DI) // err
774
775 ok:
776 XORL AX, AX // no error (it's ignored anyway)
777 MOVQ BP, SP
778 POPQ BP
779 RET
780
781 // syscall6X calls a function in libc on behalf of the syscall package.
782 // syscall6X takes a pointer to a struct like:
783 // struct {
784 // fn uintptr
785 // a1 uintptr
786 // a2 uintptr
787 // a3 uintptr
788 // a4 uintptr
789 // a5 uintptr
790 // a6 uintptr
791 // r1 uintptr
792 // r2 uintptr
793 // err uintptr
794 // }
795 // syscall6X must be called on the g0 stack with the
796 // C calling convention (use libcCall).
797 //
798 // syscall6X is like syscall6 but expects a 64-bit result
799 // and tests for 64-bit -1 to decide there was an error.
800 TEXT runtime·syscall6X(SB),NOSPLIT,$0
801 PUSHQ BP
802 MOVQ SP, BP
803 SUBQ $16, SP
804 MOVQ (0*8)(DI), R11// fn
805 MOVQ (2*8)(DI), SI // a2
806 MOVQ (3*8)(DI), DX // a3
807 MOVQ (4*8)(DI), CX // a4
808 MOVQ (5*8)(DI), R8 // a5
809 MOVQ (6*8)(DI), R9 // a6
810 MOVQ DI, (SP)
811 MOVQ (1*8)(DI), DI // a1
812 XORL AX, AX // vararg: say "no float args"
813
814 CALL R11
815
816 MOVQ (SP), DI
817 MOVQ AX, (7*8)(DI) // r1
818 MOVQ DX, (8*8)(DI) // r2
819
820 CMPQ AX, $-1
821 JNE ok
822
823 CALL libc_error(SB)
824 MOVLQSX (AX), AX
825 MOVQ (SP), DI
826 MOVQ AX, (9*8)(DI) // err
827
828 ok:
829 XORL AX, AX // no error (it's ignored anyway)
830 MOVQ BP, SP
831 POPQ BP
832 RET
833
834 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
835 // takes 5 uintptrs and 1 float64, and only returns one value,
836 // for use with standard C ABI functions.
837 TEXT runtime·syscall_x509(SB),NOSPLIT,$0
838 PUSHQ BP
839 MOVQ SP, BP
840 SUBQ $16, SP
841 MOVQ (0*8)(DI), R11// fn
842 MOVQ (2*8)(DI), SI // a2
843 MOVQ (3*8)(DI), DX // a3
844 MOVQ (4*8)(DI), CX // a4
845 MOVQ (5*8)(DI), R8 // a5
846 MOVQ (6*8)(DI), X0 // f1
847 MOVQ DI, (SP)
848 MOVQ (1*8)(DI), DI // a1
849 XORL AX, AX // vararg: say "no float args"
850
851 CALL R11
852
853 MOVQ (SP), DI
854 MOVQ AX, (7*8)(DI) // r1
855
856 XORL AX, AX // no error (it's ignored anyway)
857 MOVQ BP, SP
858 POPQ BP
859 RET
860
View as plain text