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  // Used instead of sigtramp in programs that use cgo.
   234  // Arguments from kernel are in DI, SI, DX.
   235  TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   236  	// If no traceback function, do usual sigtramp.
   237  	MOVQ	runtime·cgoTraceback(SB), AX
   238  	TESTQ	AX, AX
   239  	JZ	sigtramp
   240  
   241  	// If no traceback support function, which means that
   242  	// runtime/cgo was not linked in, do usual sigtramp.
   243  	MOVQ	_cgo_callers(SB), AX
   244  	TESTQ	AX, AX
   245  	JZ	sigtramp
   246  
   247  	// Figure out if we are currently in a cgo call.
   248  	// If not, just do usual sigtramp.
   249  	get_tls(CX)
   250  	MOVQ	g(CX),AX
   251  	TESTQ	AX, AX
   252  	JZ	sigtrampnog     // g == nil
   253  	MOVQ	g_m(AX), AX
   254  	TESTQ	AX, AX
   255  	JZ	sigtramp        // g.m == nil
   256  	MOVL	m_ncgo(AX), CX
   257  	TESTL	CX, CX
   258  	JZ	sigtramp        // g.m.ncgo == 0
   259  	MOVQ	m_curg(AX), CX
   260  	TESTQ	CX, CX
   261  	JZ	sigtramp        // g.m.curg == nil
   262  	MOVQ	g_syscallsp(CX), CX
   263  	TESTQ	CX, CX
   264  	JZ	sigtramp        // g.m.curg.syscallsp == 0
   265  	MOVQ	m_cgoCallers(AX), R8
   266  	TESTQ	R8, R8
   267  	JZ	sigtramp        // g.m.cgoCallers == nil
   268  	MOVL	m_cgoCallersUse(AX), CX
   269  	TESTL	CX, CX
   270  	JNZ	sigtramp	// g.m.cgoCallersUse != 0
   271  
   272  	// Jump to a function in runtime/cgo.
   273  	// That function, written in C, will call the user's traceback
   274  	// function with proper unwind info, and will then call back here.
   275  	// The first three arguments, and the fifth, are already in registers.
   276  	// Set the two remaining arguments now.
   277  	MOVQ	runtime·cgoTraceback(SB), CX
   278  	MOVQ	$runtime·sigtramp(SB), R9
   279  	MOVQ	_cgo_callers(SB), AX
   280  	JMP	AX
   281  
   282  sigtramp:
   283  	JMP	runtime·sigtramp(SB)
   284  
   285  sigtrampnog:
   286  	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   287  	// stack trace.
   288  	CMPL	DI, $27 // 27 == SIGPROF
   289  	JNZ	sigtramp
   290  
   291  	// Lock sigprofCallersUse.
   292  	MOVL	$0, AX
   293  	MOVL	$1, CX
   294  	MOVQ	$runtime·sigprofCallersUse(SB), R11
   295  	LOCK
   296  	CMPXCHGL	CX, 0(R11)
   297  	JNZ	sigtramp  // Skip stack trace if already locked.
   298  
   299  	// Jump to the traceback function in runtime/cgo.
   300  	// It will call back to sigprofNonGo, which will ignore the
   301  	// arguments passed in registers.
   302  	// First three arguments to traceback function are in registers already.
   303  	MOVQ	runtime·cgoTraceback(SB), CX
   304  	MOVQ	$runtime·sigprofCallers(SB), R8
   305  	MOVQ	$runtime·sigprofNonGo(SB), R9
   306  	MOVQ	_cgo_callers(SB), AX
   307  	JMP	AX
   308  
   309  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   310  	PUSHQ	BP			// make a frame; keep stack aligned
   311  	MOVQ	SP, BP
   312  	MOVQ	DI, BX
   313  	MOVQ	0(BX), DI		// arg 1 addr
   314  	MOVQ	8(BX), SI		// arg 2 len
   315  	MOVL	16(BX), DX		// arg 3 prot
   316  	MOVL	20(BX), CX		// arg 4 flags
   317  	MOVL	24(BX), R8		// arg 5 fid
   318  	MOVL	28(BX), R9		// arg 6 offset
   319  	CALL	libc_mmap(SB)
   320  	XORL	DX, DX
   321  	CMPQ	AX, $-1
   322  	JNE	ok
   323  	CALL	libc_error(SB)
   324  	MOVLQSX	(AX), DX		// errno
   325  	XORL	AX, AX
   326  ok:
   327  	MOVQ	AX, 32(BX)
   328  	MOVQ	DX, 40(BX)
   329  	POPQ	BP
   330  	RET
   331  
   332  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   333  	PUSHQ	BP
   334  	MOVQ	SP, BP
   335  	MOVQ	8(DI), SI		// arg 2 len
   336  	MOVQ	0(DI), DI		// arg 1 addr
   337  	CALL	libc_munmap(SB)
   338  	TESTQ	AX, AX
   339  	JEQ	2(PC)
   340  	MOVL	$0xf1, 0xf1  // crash
   341  	POPQ	BP
   342  	RET
   343  
   344  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   345  	PUSHQ	BP
   346  	MOVQ	SP, BP
   347  	MOVL	0(DI), DI	// arg 1 usec
   348  	CALL	libc_usleep(SB)
   349  	POPQ	BP
   350  	RET
   351  
   352  TEXT runtime·settls(SB),NOSPLIT,$32
   353  	// Nothing to do on Darwin, pthread already set thread-local storage up.
   354  	RET
   355  
   356  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   357  	PUSHQ	BP
   358  	MOVQ	SP, BP
   359  	MOVL	8(DI), SI		// arg 2 miblen
   360  	MOVQ	16(DI), DX		// arg 3 oldp
   361  	MOVQ	24(DI), CX		// arg 4 oldlenp
   362  	MOVQ	32(DI), R8		// arg 5 newp
   363  	MOVQ	40(DI), R9		// arg 6 newlen
   364  	MOVQ	0(DI), DI		// arg 1 mib
   365  	CALL	libc_sysctl(SB)
   366  	POPQ	BP
   367  	RET
   368  
   369  TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
   370  	PUSHQ	BP
   371  	MOVQ	SP, BP
   372  	MOVQ	8(DI), SI		// arg 2 oldp
   373  	MOVQ	16(DI), DX		// arg 3 oldlenp
   374  	MOVQ	24(DI), CX		// arg 4 newp
   375  	MOVQ	32(DI), R8		// arg 5 newlen
   376  	MOVQ	0(DI), DI		// arg 1 name
   377  	CALL	libc_sysctlbyname(SB)
   378  	POPQ	BP
   379  	RET
   380  
   381  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   382  	PUSHQ	BP
   383  	MOVQ	SP, BP
   384  	CALL	libc_kqueue(SB)
   385  	POPQ	BP
   386  	RET
   387  
   388  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   389  	PUSHQ	BP
   390  	MOVQ	SP, BP
   391  	MOVQ	8(DI), SI		// arg 2 keventt
   392  	MOVL	16(DI), DX		// arg 3 nch
   393  	MOVQ	24(DI), CX		// arg 4 ev
   394  	MOVL	32(DI), R8		// arg 5 nev
   395  	MOVQ	40(DI), R9		// arg 6 ts
   396  	MOVL	0(DI), DI		// arg 1 kq
   397  	CALL	libc_kevent(SB)
   398  	CMPL	AX, $-1
   399  	JNE	ok
   400  	CALL	libc_error(SB)
   401  	MOVLQSX	(AX), AX		// errno
   402  	NEGQ	AX			// caller wants it as a negative error code
   403  ok:
   404  	POPQ	BP
   405  	RET
   406  
   407  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   408  	PUSHQ	BP
   409  	MOVQ	SP, BP
   410  	MOVL	4(DI), SI		// arg 2 cmd
   411  	MOVL	8(DI), DX		// arg 3 arg
   412  	MOVL	0(DI), DI		// arg 1 fd
   413  	XORL	AX, AX			// vararg: say "no float args"
   414  	CALL	libc_fcntl(SB)
   415  	POPQ	BP
   416  	RET
   417  
   418  // mstart_stub is the first function executed on a new thread started by pthread_create.
   419  // It just does some low-level setup and then calls mstart.
   420  // Note: called with the C calling convention.
   421  TEXT runtime·mstart_stub(SB),NOSPLIT,$0
   422  	// DI points to the m.
   423  	// We are already on m's g0 stack.
   424  
   425  	// Transition from C ABI to Go ABI.
   426  	PUSH_REGS_HOST_TO_ABI0()
   427  
   428  	MOVQ	m_g0(DI), DX // g
   429  
   430  	// Initialize TLS entry.
   431  	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
   432  	MOVQ	DX, 0x30(GS)
   433  
   434  	CALL	runtime·mstart(SB)
   435  
   436  	POP_REGS_HOST_TO_ABI0()
   437  
   438  	// Go is all done with this OS thread.
   439  	// Tell pthread everything is ok (we never join with this thread, so
   440  	// the value here doesn't really matter).
   441  	XORL	AX, AX
   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  TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
   558  	PUSHQ	BP
   559  	MOVQ	SP, BP
   560  	MOVQ	DI, BX		// BX is caller-save
   561  	CALL	libc_pthread_self(SB)
   562  	MOVQ	AX, 0(BX)	// return value
   563  	POPQ	BP
   564  	RET
   565  
   566  TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
   567  	PUSHQ	BP
   568  	MOVQ	SP, BP
   569  	MOVQ	8(DI), SI	// arg 2 sig
   570  	MOVQ	0(DI), DI	// arg 1 thread
   571  	CALL	libc_pthread_kill(SB)
   572  	POPQ	BP
   573  	RET
   574  
   575  // syscall calls a function in libc on behalf of the syscall package.
   576  // syscall takes a pointer to a struct like:
   577  // struct {
   578  //	fn    uintptr
   579  //	a1    uintptr
   580  //	a2    uintptr
   581  //	a3    uintptr
   582  //	r1    uintptr
   583  //	r2    uintptr
   584  //	err   uintptr
   585  // }
   586  // syscall must be called on the g0 stack with the
   587  // C calling convention (use libcCall).
   588  //
   589  // syscall expects a 32-bit result and tests for 32-bit -1
   590  // to decide there was an error.
   591  TEXT runtime·syscall(SB),NOSPLIT,$0
   592  	PUSHQ	BP
   593  	MOVQ	SP, BP
   594  	SUBQ	$16, SP
   595  	MOVQ	(0*8)(DI), CX // fn
   596  	MOVQ	(2*8)(DI), SI // a2
   597  	MOVQ	(3*8)(DI), DX // a3
   598  	MOVQ	DI, (SP)
   599  	MOVQ	(1*8)(DI), DI // a1
   600  	XORL	AX, AX	      // vararg: say "no float args"
   601  
   602  	CALL	CX
   603  
   604  	MOVQ	(SP), DI
   605  	MOVQ	AX, (4*8)(DI) // r1
   606  	MOVQ	DX, (5*8)(DI) // r2
   607  
   608  	// Standard libc functions return -1 on error
   609  	// and set errno.
   610  	CMPL	AX, $-1	      // Note: high 32 bits are junk
   611  	JNE	ok
   612  
   613  	// Get error code from libc.
   614  	CALL	libc_error(SB)
   615  	MOVLQSX	(AX), AX
   616  	MOVQ	(SP), DI
   617  	MOVQ	AX, (6*8)(DI) // err
   618  
   619  ok:
   620  	XORL	AX, AX        // no error (it's ignored anyway)
   621  	MOVQ	BP, SP
   622  	POPQ	BP
   623  	RET
   624  
   625  // syscallX calls a function in libc on behalf of the syscall package.
   626  // syscallX takes a pointer to a struct like:
   627  // struct {
   628  //	fn    uintptr
   629  //	a1    uintptr
   630  //	a2    uintptr
   631  //	a3    uintptr
   632  //	r1    uintptr
   633  //	r2    uintptr
   634  //	err   uintptr
   635  // }
   636  // syscallX must be called on the g0 stack with the
   637  // C calling convention (use libcCall).
   638  //
   639  // syscallX is like syscall but expects a 64-bit result
   640  // and tests for 64-bit -1 to decide there was an error.
   641  TEXT runtime·syscallX(SB),NOSPLIT,$0
   642  	PUSHQ	BP
   643  	MOVQ	SP, BP
   644  	SUBQ	$16, SP
   645  	MOVQ	(0*8)(DI), CX // fn
   646  	MOVQ	(2*8)(DI), SI // a2
   647  	MOVQ	(3*8)(DI), DX // a3
   648  	MOVQ	DI, (SP)
   649  	MOVQ	(1*8)(DI), DI // a1
   650  	XORL	AX, AX	      // vararg: say "no float args"
   651  
   652  	CALL	CX
   653  
   654  	MOVQ	(SP), DI
   655  	MOVQ	AX, (4*8)(DI) // r1
   656  	MOVQ	DX, (5*8)(DI) // r2
   657  
   658  	// Standard libc functions return -1 on error
   659  	// and set errno.
   660  	CMPQ	AX, $-1
   661  	JNE	ok
   662  
   663  	// Get error code from libc.
   664  	CALL	libc_error(SB)
   665  	MOVLQSX	(AX), AX
   666  	MOVQ	(SP), DI
   667  	MOVQ	AX, (6*8)(DI) // err
   668  
   669  ok:
   670  	XORL	AX, AX        // no error (it's ignored anyway)
   671  	MOVQ	BP, SP
   672  	POPQ	BP
   673  	RET
   674  
   675  // syscallPtr is like syscallX except that the libc function reports an
   676  // error by returning NULL and setting errno.
   677  TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   678  	PUSHQ	BP
   679  	MOVQ	SP, BP
   680  	SUBQ	$16, SP
   681  	MOVQ	(0*8)(DI), CX // fn
   682  	MOVQ	(2*8)(DI), SI // a2
   683  	MOVQ	(3*8)(DI), DX // a3
   684  	MOVQ	DI, (SP)
   685  	MOVQ	(1*8)(DI), DI // a1
   686  	XORL	AX, AX	      // vararg: say "no float args"
   687  
   688  	CALL	CX
   689  
   690  	MOVQ	(SP), DI
   691  	MOVQ	AX, (4*8)(DI) // r1
   692  	MOVQ	DX, (5*8)(DI) // r2
   693  
   694  	// syscallPtr libc functions return NULL on error
   695  	// and set errno.
   696  	TESTQ	AX, AX
   697  	JNE	ok
   698  
   699  	// Get error code from libc.
   700  	CALL	libc_error(SB)
   701  	MOVLQSX	(AX), AX
   702  	MOVQ	(SP), DI
   703  	MOVQ	AX, (6*8)(DI) // err
   704  
   705  ok:
   706  	XORL	AX, AX        // no error (it's ignored anyway)
   707  	MOVQ	BP, SP
   708  	POPQ	BP
   709  	RET
   710  
   711  // syscall6 calls a function in libc on behalf of the syscall package.
   712  // syscall6 takes a pointer to a struct like:
   713  // struct {
   714  //	fn    uintptr
   715  //	a1    uintptr
   716  //	a2    uintptr
   717  //	a3    uintptr
   718  //	a4    uintptr
   719  //	a5    uintptr
   720  //	a6    uintptr
   721  //	r1    uintptr
   722  //	r2    uintptr
   723  //	err   uintptr
   724  // }
   725  // syscall6 must be called on the g0 stack with the
   726  // C calling convention (use libcCall).
   727  //
   728  // syscall6 expects a 32-bit result and tests for 32-bit -1
   729  // to decide there was an error.
   730  TEXT runtime·syscall6(SB),NOSPLIT,$0
   731  	PUSHQ	BP
   732  	MOVQ	SP, BP
   733  	SUBQ	$16, SP
   734  	MOVQ	(0*8)(DI), R11// fn
   735  	MOVQ	(2*8)(DI), SI // a2
   736  	MOVQ	(3*8)(DI), DX // a3
   737  	MOVQ	(4*8)(DI), CX // a4
   738  	MOVQ	(5*8)(DI), R8 // a5
   739  	MOVQ	(6*8)(DI), R9 // a6
   740  	MOVQ	DI, (SP)
   741  	MOVQ	(1*8)(DI), DI // a1
   742  	XORL	AX, AX	      // vararg: say "no float args"
   743  
   744  	CALL	R11
   745  
   746  	MOVQ	(SP), DI
   747  	MOVQ	AX, (7*8)(DI) // r1
   748  	MOVQ	DX, (8*8)(DI) // r2
   749  
   750  	CMPL	AX, $-1
   751  	JNE	ok
   752  
   753  	CALL	libc_error(SB)
   754  	MOVLQSX	(AX), AX
   755  	MOVQ	(SP), DI
   756  	MOVQ	AX, (9*8)(DI) // err
   757  
   758  ok:
   759  	XORL	AX, AX        // no error (it's ignored anyway)
   760  	MOVQ	BP, SP
   761  	POPQ	BP
   762  	RET
   763  
   764  // syscall6X calls a function in libc on behalf of the syscall package.
   765  // syscall6X takes a pointer to a struct like:
   766  // struct {
   767  //	fn    uintptr
   768  //	a1    uintptr
   769  //	a2    uintptr
   770  //	a3    uintptr
   771  //	a4    uintptr
   772  //	a5    uintptr
   773  //	a6    uintptr
   774  //	r1    uintptr
   775  //	r2    uintptr
   776  //	err   uintptr
   777  // }
   778  // syscall6X must be called on the g0 stack with the
   779  // C calling convention (use libcCall).
   780  //
   781  // syscall6X is like syscall6 but expects a 64-bit result
   782  // and tests for 64-bit -1 to decide there was an error.
   783  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   784  	PUSHQ	BP
   785  	MOVQ	SP, BP
   786  	SUBQ	$16, SP
   787  	MOVQ	(0*8)(DI), R11// fn
   788  	MOVQ	(2*8)(DI), SI // a2
   789  	MOVQ	(3*8)(DI), DX // a3
   790  	MOVQ	(4*8)(DI), CX // a4
   791  	MOVQ	(5*8)(DI), R8 // a5
   792  	MOVQ	(6*8)(DI), R9 // a6
   793  	MOVQ	DI, (SP)
   794  	MOVQ	(1*8)(DI), DI // a1
   795  	XORL	AX, AX	      // vararg: say "no float args"
   796  
   797  	CALL	R11
   798  
   799  	MOVQ	(SP), DI
   800  	MOVQ	AX, (7*8)(DI) // r1
   801  	MOVQ	DX, (8*8)(DI) // r2
   802  
   803  	CMPQ	AX, $-1
   804  	JNE	ok
   805  
   806  	CALL	libc_error(SB)
   807  	MOVLQSX	(AX), AX
   808  	MOVQ	(SP), DI
   809  	MOVQ	AX, (9*8)(DI) // err
   810  
   811  ok:
   812  	XORL	AX, AX        // no error (it's ignored anyway)
   813  	MOVQ	BP, SP
   814  	POPQ	BP
   815  	RET
   816  
   817  // syscallNoErr is like syscall6 but does not check for errors, and
   818  // only returns one value, for use with standard C ABI library functions.
   819  TEXT runtime·syscallNoErr(SB),NOSPLIT,$0
   820  	PUSHQ	BP
   821  	MOVQ	SP, BP
   822  	SUBQ	$16, SP
   823  	MOVQ	(0*8)(DI), R11// fn
   824  	MOVQ	(2*8)(DI), SI // a2
   825  	MOVQ	(3*8)(DI), DX // a3
   826  	MOVQ	(4*8)(DI), CX // a4
   827  	MOVQ	(5*8)(DI), R8 // a5
   828  	MOVQ	(6*8)(DI), R9 // a6
   829  	MOVQ	DI, (SP)
   830  	MOVQ	(1*8)(DI), DI // a1
   831  	XORL	AX, AX	      // vararg: say "no float args"
   832  
   833  	CALL	R11
   834  
   835  	MOVQ	(SP), DI
   836  	MOVQ	AX, (7*8)(DI) // r1
   837  
   838  	XORL	AX, AX        // no error (it's ignored anyway)
   839  	MOVQ	BP, SP
   840  	POPQ	BP
   841  	RET
   842  

View as plain text