...

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