github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/runtime/sys_darwin_amd64.s (about)

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