Black Lives Matter. Support the Equal Justice Initiative.

Text file src/runtime/sys_darwin_amd64.s

Documentation: runtime

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

View as plain text