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